mFragments = new ArrayMap<>();
49 |
50 | public ViewPagerAdapterFragment(FragmentManager fm, Context context) {
51 | super(fm);
52 | mContext = context;
53 | }
54 |
55 | public void addTab(@Nullable String title, @NonNull String tag, Class> clss, @Nullable Bundle args) {
56 | ViewPageInfo viewPageInfo = new ViewPageInfo(title, tag, clss, args);
57 | mTabs.add(viewPageInfo);
58 | }
59 |
60 | @Override
61 | public int getCount() {
62 | return mTabs.size();
63 | }
64 |
65 | @Override
66 | public int getItemPosition(Object object) {
67 | return PagerAdapter.POSITION_NONE;
68 | }
69 |
70 | @Override
71 | public Fragment getItem(int position) {
72 | ViewPageInfo info = mTabs.get(position);
73 |
74 | Fragment fragment = mFragments.get(info.tag);
75 | if (fragment == null) {
76 | fragment = Fragment.instantiate(mContext, info.clss.getName(), info.args);
77 | // 避免重复创建而进行缓存
78 | mFragments.put(info.tag, fragment);
79 | }
80 |
81 | return fragment;
82 | }
83 |
84 | @Override
85 | public CharSequence getPageTitle(int position) {
86 | return mTabs.get(position).title;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/java/com/vea/atoms/mvp/commonsdk/core/GlobalHttpHandlerImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.commonsdk.core;
17 |
18 | import android.content.Context;
19 |
20 | import com.vea.atoms.mvp.http.GlobalHttpHandler;
21 |
22 | import okhttp3.Interceptor;
23 | import okhttp3.Request;
24 | import okhttp3.Response;
25 |
26 | /**
27 | * ================================================
28 | * 展示 {@link GlobalHttpHandler} 的用法
29 | *
30 | * Created by Vea on 04/09/2017 17:06
31 | * ================================================
32 | */
33 | public class GlobalHttpHandlerImpl implements GlobalHttpHandler {
34 | private Context context;
35 |
36 | public GlobalHttpHandlerImpl(Context context) {
37 | this.context = context;
38 | }
39 |
40 | /**
41 | * 这里可以先客户端一步拿到每一次 Http 请求的结果, 可以先解析成 Json, 再做一些操作, 如检测到 token 过期后
42 | * 重新请求 token, 并重新执行请求
43 | *
44 | * @param httpResult 服务器返回的结果 (已被框架自动转换为字符串)
45 | * @param chain {@link okhttp3.Interceptor.Chain}
46 | * @param response {@link Response}
47 | * @return
48 | */
49 | @Override
50 | public Response onHttpResultResponse(String httpResult, Interceptor.Chain chain, Response response) {
51 | /* 这里如果发现 token 过期, 可以先请求最新的 token, 然后在拿新的 token 放入 Request 里去重新请求
52 | 注意在这个回调之前已经调用过 proceed(), 所以这里必须自己去建立网络请求, 如使用 Okhttp 使用新的 Request 去请求
53 | create a new request and modify it accordingly using the new token
54 | Request newRequest = chain.request().newBuilder().header("token", newToken)
55 | .build();
56 |
57 | retry the request
58 |
59 | response.body().close();
60 | 如果使用 Okhttp 将新的请求, 请求成功后, 再将 Okhttp 返回的 Response return 出去即可
61 | 如果不需要返回新的结果, 则直接把参数 response 返回出去即可 */
62 | return response;
63 | }
64 |
65 | /**
66 | * 这里可以在请求服务器之前拿到 {@link Request}, 做一些操作比如给 {@link Request} 统一添加 token 或者 header 以及参数加密等操作
67 | *
68 | * @param chain {@link okhttp3.Interceptor.Chain}
69 | * @param request {@link Request}
70 | * @return
71 | */
72 | @Override
73 | public Request onHttpRequestBefore(Interceptor.Chain chain, Request request) {
74 | /* 如果需要再请求服务器之前做一些操作, 则重新返回一个做过操作的的 Request 如增加 Header, 不做操作则直接返回参数 request
75 | return chain.request().newBuilder().header("token", tokenId)
76 | .build(); */
77 | return request;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/java/com/vea/atoms/mvp/commonsdk/core/RouterHub.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.commonsdk.core;
17 |
18 | /**
19 | * ================================================
20 | * RouterHub 用来定义路由器的路由地址, 以组件名作为前缀, 对每个组件的路由地址进行分组, 可以统一查看和管理所有分组的路由地址
21 | *
22 | * RouterHub 存在于基础库, 可以被看作是所有组件都需要遵守的通讯协议, 里面不仅可以放路由地址常量, 还可以放跨组件传递数据时命名的各种 Key 值
23 | * 再配以适当注释, 任何组件开发人员不需要事先沟通只要依赖了这个协议, 就知道了各自该怎样协同工作, 既提高了效率又降低了出错风险, 约定的东西自然要比口头上说强
24 | *
25 | * 如果您觉得把每个路由地址都写在基础库的 RouterHub 中, 太麻烦了, 也可以在每个组件内部建立一个私有 RouterHub, 将不需要跨组件的
26 | * 路由地址放入私有 RouterHub 中管理, 只将需要跨组件的路由地址放入基础库的公有 RouterHub 中管理, 如果您不需要集中管理所有路由地址的话
27 | * 这也是比较推荐的一种方式
28 | *
29 | * 路由地址的命名规则为 组件名 + 页面名, 如订单组件的订单详情页的路由地址可以命名为 "/order/OrderDetailActivity"
30 | *
31 | * ARouter 将路由地址中第一个 '/' 后面的字符称为 Group, 比如上面的示例路由地址中 order 就是 Group, 以 order 开头的地址都被分配该 Group 下
32 | * 切记不同的组件中不能出现名称一样的 Group, 否则会发生该 Group 下的部分路由地址找不到的情况!!!
33 | * 所以每个组件使用自己的组件名作为 Group 是比较好的选择, 毕竟组件不会重名
34 | *
35 | * Created by Vea on 2018/8/25
36 | * ================================================
37 | */
38 | public interface RouterHub {
39 | /**
40 | * 组名
41 | */
42 | String APP = "/app";//宿主 App 组件
43 |
44 | String GANK = "/gank";//干货集中营组件
45 |
46 | /* app =============================================================*/
47 | String APP_MAIN_ACTIVITY = APP + "/MainActivity";
48 |
49 |
50 | /* gank =============================================================*/
51 | String GANK_MAIN_ACTIVITY = GANK + "/GankMainActivity";
52 | }
53 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/java/com/vea/atoms/mvp/commonsdk/http/Api.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.commonsdk.http;
17 |
18 | /**
19 | * ================================================
20 | * CommonSDK 的 Api 可以定义公用的关于 API 的相关常量, 比如说请求地址, 错误码等, 每个组件的 Api 可以定义组件自己的私有常量
21 | *
22 | * Created by Vea on 30/03/2018 17:16
23 | * ================================================
24 | */
25 | public interface Api {
26 | String APP_DOMAIN = "https://api.github.com";
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/java/com/vea/atoms/mvp/commonsdk/utils/ARouterUtils.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.commonsdk.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 |
6 | import com.alibaba.android.arouter.launcher.ARouter;
7 |
8 | /**
9 | * ARouter 工具类
10 | *
11 | * @author lishide
12 | * @date 2018/10/08
13 | */
14 | public class ARouterUtils {
15 | private ARouterUtils() {
16 | throw new IllegalStateException("you can't instantiate me!");
17 | }
18 |
19 | /**
20 | * 使用 {@link ARouter} 根据 {@code path} 跳转到对应的页面, 这个方法因为没有使用 {@link Activity} 跳转
21 | * 所以 {@link ARouter} 会自动给 {@link android.content.Intent} 加上 Intent.FLAG_ACTIVITY_NEW_TASK
22 | * 如果不想自动加上这个 Flag 请使用 {@link ARouter#getInstance()#navigation(Context, String)} 并传入 {@link Activity}
23 | *
24 | * @param path {@code path}
25 | */
26 | public static void navigation(String path) {
27 | ARouter.getInstance().build(path).navigation();
28 | }
29 |
30 | /**
31 | * 使用 {@link ARouter} 根据 {@code path} 跳转到对应的页面, 如果参数 {@code context} 传入的不是 {@link Activity}
32 | * {@link ARouter} 就会自动给 {@link android.content.Intent} 加上 Intent.FLAG_ACTIVITY_NEW_TASK
33 | * 如果不想自动加上这个 Flag 请使用 {@link Activity} 作为 {@code context} 传入
34 | *
35 | * @param context
36 | * @param path
37 | */
38 | public static void navigation(Context context, String path) {
39 | ARouter.getInstance().build(path).navigation(context);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/java/com/vea/atoms/mvp/commonsdk/utils/ImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.commonsdk.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapShader;
6 | import android.graphics.Canvas;
7 | import android.graphics.Paint;
8 | import android.widget.ImageView;
9 |
10 | import com.bumptech.glide.Glide;
11 | import com.bumptech.glide.Priority;
12 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
13 | import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
14 | import com.bumptech.glide.request.RequestOptions;
15 |
16 | import java.security.MessageDigest;
17 |
18 | /**
19 | * ================================================
20 | * Glide 图片加载辅助类,支持圆形图片
21 | *
22 | * Created by Vea on 30/03/2018 17:16
23 | * ================================================
24 | */
25 | public class ImageLoader {
26 |
27 | private ImageLoader() {
28 | }
29 |
30 | public static void load(Context context, ImageView view, String url) {
31 | Glide.with(context).load(url).into(view);
32 | }
33 |
34 | public static void load(Context context, ImageView view, int drawableRes) {
35 | Glide.with(context).load(drawableRes).into(view);
36 | }
37 |
38 | /**
39 | * @param placeholder 加载中的图片
40 | * @param error 加载失败显示的图片
41 | */
42 | public static void load(Context context, ImageView view, String url, int placeholder, int error) {
43 | RequestOptions options = new RequestOptions()
44 | .centerCrop()
45 | .placeholder(placeholder)
46 | .error(error)
47 | .priority(Priority.HIGH);
48 |
49 | Glide.with(context).load(url).apply(options).into(view);
50 | }
51 |
52 | /**
53 | * 加载圆形图片
54 | *
55 | * @param context
56 | * @param view
57 | * @param url
58 | */
59 | public static void loadCircleImage(Context context, ImageView view, String url) {
60 | RequestOptions options = new RequestOptions()
61 | .centerCrop()
62 | .priority(Priority.HIGH)
63 | .transform(new GlideCircleTransform());
64 | Glide.with(context).load(url).apply(options).into(view);
65 | }
66 |
67 | /**
68 | * 加载圆形图片
69 | *
70 | * @param context
71 | * @param view
72 | * @param url
73 | * @param error
74 | */
75 | public static void loadCircleImage(Context context, ImageView view, String url, int error) {
76 | RequestOptions options = new RequestOptions()
77 | .centerCrop()
78 | .placeholder(error)
79 | .error(error)
80 | .priority(Priority.HIGH)
81 | .transform(new GlideCircleTransform());
82 | Glide.with(context).load(url).apply(options).into(view);
83 | }
84 |
85 | public static class GlideCircleTransform extends BitmapTransformation {
86 |
87 | public GlideCircleTransform() {
88 | super();
89 | }
90 |
91 | @Override
92 | public Bitmap transform(BitmapPool pool, Bitmap toTransform,
93 | int outWidth, int outHeight) {
94 | return circleCrop(pool, toTransform);
95 | }
96 |
97 | private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
98 | if (source == null) return null;
99 | int size = Math.min(source.getWidth(), source.getHeight());
100 | int x = (source.getWidth() - size) / 2;
101 | int y = (source.getHeight() - size) / 2;
102 |
103 | Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
104 | Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
105 | if (result == null) {
106 | result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
107 | }
108 | Canvas canvas = new Canvas(result);
109 | Paint paint = new Paint();
110 | paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
111 | paint.setAntiAlias(true);
112 | float r = size / 2f;
113 | canvas.drawCircle(r, r, r, paint);
114 | return result;
115 | }
116 |
117 | @Override
118 | public void updateDiskCacheKey(MessageDigest messageDigest) {
119 |
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/res/layout/public_recycler_footer_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
21 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #663366
4 | #663366
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CommonSDK
3 |
4 |
--------------------------------------------------------------------------------
/CommonSDK/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
--------------------------------------------------------------------------------
/CommonService/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/CommonService/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
6 |
7 | defaultConfig {
8 | minSdkVersion rootProject.ext.android["minSdkVersion"]
9 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
10 | versionCode Integer.parseInt(APP_CODE)
11 | versionName APP_VERSION
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 |
14 | }
15 |
16 | buildTypes {
17 | release {
18 | postprocessing {
19 | removeUnusedCode false
20 | removeUnusedResources false
21 | obfuscate false
22 | optimizeCode false
23 | proguardFile 'proguard-rules.pro'
24 | }
25 | }
26 | }
27 |
28 | }
29 |
30 | dependencies {
31 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/CommonService/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/CommonService/src/androidTest/java/org/vea/atoms/mvp/commonservice/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package org.vea.atoms.mvp.commonservice;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("org.vea.atoms.mvp.commonservice.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/CommonService/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/CommonService/src/main/java/org/vea/atoms/mvp/commonservice/IUserService.java:
--------------------------------------------------------------------------------
1 | package org.vea.atoms.mvp.commonservice;
2 |
3 |
4 | /**
5 | * ================================================
6 | * 向外提供数据传递接口服务
7 | *
8 | * Created by Vea on 2018/8/30.
9 | * ================================================
10 | */
11 | public interface IUserService {
12 | String getAvatarUrl();
13 |
14 | int getId();
15 |
16 | String getLogin();
17 |
18 | void setAvatarUrl(String avatar_url);
19 |
20 | void setId(int id);
21 |
22 | void setLogin(String login);
23 | }
24 |
--------------------------------------------------------------------------------
/CommonService/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CommonService
3 |
4 |
--------------------------------------------------------------------------------
/CommonService/src/test/java/org/vea/atoms/mvp/commonservice/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package org.vea.atoms.mvp.commonservice;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/Module-gank/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/Module-gank/build.gradle:
--------------------------------------------------------------------------------
1 | if (isRunGankModule.toBoolean()) {
2 | apply plugin: 'com.android.application'
3 | } else {
4 | apply plugin: 'com.android.library'
5 | }
6 | apply plugin: 'com.jakewharton.butterknife'
7 | apply plugin: 'kotlin-android'
8 | android {
9 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
10 |
11 | defaultConfig {
12 | minSdkVersion rootProject.ext.android["minSdkVersion"]
13 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
14 | versionCode Integer.parseInt(APP_CODE)
15 | versionName APP_VERSION
16 |
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 |
19 | javaCompileOptions {
20 | annotationProcessorOptions {
21 | arguments = [moduleName: project.getName()]
22 | includeCompileClasspath true
23 | }
24 | }
25 |
26 | }
27 |
28 | buildTypes {
29 | release {
30 | minifyEnabled false
31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
32 | }
33 | }
34 |
35 |
36 | compileOptions {
37 | targetCompatibility JavaVersion.VERSION_1_8
38 | sourceCompatibility JavaVersion.VERSION_1_8
39 | }
40 |
41 | resourcePrefix "gank_" //给 Module 内的资源名增加前缀, 避免资源名冲突
42 |
43 |
44 | sourceSets {
45 | main {
46 | jniLibs.srcDirs = ['libs']
47 | if (isRunGankModule.toBoolean()) {
48 | manifest.srcFile 'src/main/debug/AndroidManifest.xml'
49 | } else {
50 | manifest.srcFile 'src/main/AndroidManifest.xml'
51 | }
52 | }
53 | }
54 |
55 | }
56 |
57 | dependencies {
58 | implementation fileTree(dir: 'libs', include: ['*.jar'])
59 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
60 |
61 | testImplementation rootProject.ext.dependencies["junit"]
62 | androidTestImplementation rootProject.ext.dependencies["runner"]
63 | androidTestImplementation rootProject.ext.dependencies["espresso-core"]
64 |
65 | api project(':CommonSDK')
66 | api project(":CommonService")
67 |
68 |
69 | if (isRunGankModule.toBoolean()) {
70 |
71 | annotationProcessor rootProject.ext.dependencies["arouter-compiler"]
72 | annotationProcessor rootProject.ext.dependencies["butterknife-compiler"]
73 | annotationProcessor rootProject.ext.dependencies["dagger2-compiler"]
74 |
75 | debugImplementation rootProject.ext.dependencies["canary-debug"]
76 | releaseImplementation rootProject.ext.dependencies["canary-release"]
77 | } else {
78 | compileOnly rootProject.ext.dependencies["arouter-compiler"]
79 | compileOnly rootProject.ext.dependencies["butterknife-compiler"]
80 | compileOnly rootProject.ext.dependencies["dagger2-compiler"]
81 |
82 | compileOnly rootProject.ext.dependencies["canary-debug"]
83 | compileOnly rootProject.ext.dependencies["canary-release"]
84 | }
85 |
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/Module-gank/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/Module-gank/src/androidTest/java/com/vea/atoms/mvp/gank/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.gank;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.vea.atoms.mvp.gank.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Module-gank/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Module-gank/src/main/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
25 |
28 |
31 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/app/AppLifecyclesImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.app;
17 |
18 | import android.app.Application;
19 | import android.content.Context;
20 | import android.support.annotation.NonNull;
21 |
22 | import com.squareup.leakcanary.LeakCanary;
23 | import com.vea.atoms.mvp.app.AppLifecycles;
24 | import com.vea.atoms.mvp.gank.BuildConfig;
25 | import com.vea.atoms.mvp.gank.mvp.model.service.GankService;
26 |
27 | import me.jessyan.retrofiturlmanager.RetrofitUrlManager;
28 |
29 |
30 | /**
31 | * ================================================
32 | * 展示 {@link AppLifecycles} 的用法
33 | *
34 | * Created by Vea on 2018/8/20
35 | * ================================================
36 | */
37 | public class AppLifecyclesImpl implements AppLifecycles {
38 |
39 | @Override
40 | public void attachBaseContext(@NonNull Application application, @NonNull Context base) {
41 |
42 | }
43 |
44 | @Override
45 | public void onCreate(@NonNull Application application) {
46 | if (LeakCanary.isInAnalyzerProcess(application)) {
47 | // This process is dedicated to LeakCanary for heap analysis.
48 | // You should not init your app in this process.
49 | return;
50 | }
51 | //使用 RetrofitUrlManager 切换 BaseUrl
52 | RetrofitUrlManager.getInstance().putDomain(GankService.GANK_DOMAIN_NAME, GankService.GANK_DOMAIN);
53 | if (!BuildConfig.DEBUG) {
54 | LeakCanary.install(application);
55 | }
56 | }
57 |
58 | @Override
59 | public void onTerminate(@NonNull Application application) {
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/app/GankConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.app;
17 |
18 |
19 | /**
20 | * ================================================
21 | * 存放一些静态的变量
22 | *
23 | * Created by Vea on 2016/11/24
24 | * ================================================
25 | */
26 | public interface GankConstants {
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/app/GlobalConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.app;
17 |
18 | import android.content.Context;
19 |
20 | import com.vea.atoms.mvp.app.AppDelegate;
21 | import com.vea.atoms.mvp.app.AppLifecycles;
22 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
23 | import com.vea.atoms.mvp.integration.ConfigModule;
24 | import com.vea.atoms.mvp.integration.ManifestParser;
25 |
26 | import java.util.List;
27 |
28 |
29 | /**
30 | * ================================================
31 | * 组件的全局配置信息在此配置, 需要将此实现类声明到 AndroidManifest 中
32 | * CommonSDK 中已有 {@link GlobalConfiguration} 配置有所有组件都可公用的配置信息
33 | * 这里用来配置一些组件自身私有的配置信息
34 | *
35 | * @see AppDelegate
36 | * @see ManifestParser
37 | * Created by Vea on 12/04/2017 17:25
38 | * ================================================
39 | */
40 | public final class GlobalConfiguration implements ConfigModule {
41 |
42 | @Override
43 | public void applyOptions(Context context, GlobalConfigModule.Builder builder) {
44 |
45 | }
46 |
47 | @Override
48 | public void injectAppLifecycle(Context context, List lifecycles) {
49 | // AppLifecycles 的所有方法都会在基类 Application 的对应的生命周期中被调用,所以在对应的方法中可以扩展一些自己需要的逻辑
50 | // 可以根据不同的逻辑添加多个实现类
51 | lifecycles.add(new AppLifecyclesImpl());
52 | }
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/di/component/GankComponent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.di.component;
17 |
18 | import com.vea.atoms.mvp.di.component.AppComponent;
19 | import com.vea.atoms.mvp.di.scope.ActivityScope;
20 | import com.vea.atoms.mvp.gank.di.module.GankModule;
21 | import com.vea.atoms.mvp.gank.mvp.contract.GirlContract;
22 | import com.vea.atoms.mvp.gank.mvp.ui.fragment.GirlFragment;
23 |
24 | import dagger.BindsInstance;
25 | import dagger.Component;
26 |
27 | /**
28 | * ================================================
29 | * 展示 Component 的用法
30 | *
31 | * Created by Vea on 09/04/2016 11:17
32 | * ================================================
33 | */
34 | @ActivityScope
35 | @Component(modules = GankModule.class, dependencies = AppComponent.class)
36 | public interface GankComponent {
37 |
38 | void inject(GirlFragment activity);
39 |
40 | @Component.Builder
41 | interface Builder {
42 | @BindsInstance
43 | GankComponent.Builder view(GirlContract.View view);
44 |
45 | GankComponent.Builder appComponent(AppComponent appComponent);
46 |
47 | GankComponent build();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/di/module/GankModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.di.module;
17 |
18 | import com.vea.atoms.mvp.commonsdk.adapter.BaseRecyclerAdapter;
19 | import com.vea.atoms.mvp.di.scope.ActivityScope;
20 | import com.vea.atoms.mvp.gank.mvp.contract.GirlContract;
21 | import com.vea.atoms.mvp.gank.mvp.ui.adapter.GirlListAdapter;
22 |
23 | import dagger.Module;
24 | import dagger.Provides;
25 |
26 | /**
27 | * ================================================
28 | * 展示 Module 的用法
29 | *
30 | * Created by Vea on 09/04/2016 11:10
31 | * ================================================
32 | */
33 | @Module
34 | public class GankModule {
35 |
36 | @ActivityScope
37 | @Provides
38 | static GirlListAdapter provideListAdapter(GirlContract.View view) {
39 | GirlListAdapter adapter = new GirlListAdapter(view.getFragmentActivity());
40 | adapter.setState(BaseRecyclerAdapter.STATE_HIDE, false);
41 | return adapter;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/contract/GirlContract.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.contract;
17 |
18 | import android.app.Activity;
19 |
20 | import com.vea.atoms.mvp.base.IPresenter;
21 | import com.vea.atoms.mvp.base.IView;
22 | import com.vea.atoms.mvp.gank.mvp.model.entity.GankItemBean;
23 | import com.vea.atoms.mvp.gank.mvp.presenter.GirlPresenter;
24 | import com.vea.atoms.mvp.gank.mvp.ui.fragment.GirlFragment;
25 |
26 | import java.util.List;
27 |
28 | /**
29 | * ================================================
30 | * 约定协议
31 | *
32 | * @see GirlPresenter
33 | * @see GirlFragment
34 | * Created by Vea on 2016/11/24
35 | * ================================================
36 | */
37 | public interface GirlContract {
38 |
39 | interface View extends IView {
40 |
41 | void getGankDataSuccess(List mList, boolean isRefresh);
42 |
43 | /**
44 | * @param isRefresh 刷新为true,加载更多为false
45 | */
46 | void getGankDataFailure(boolean isRefresh);
47 |
48 | Activity getFragmentActivity();
49 | }
50 |
51 | interface Presenter extends IPresenter {
52 |
53 | void getGankData(boolean isRefresh);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/model/entity/GankBaseResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.model.entity;
17 |
18 |
19 | /**
20 | * ================================================
21 | * 如果你服务器返回的数据格式固定为这种方式(这里只提供思想,服务器返回的数据格式可能不一致,可根据自家服务器返回的格式作更改)
22 | * 指定范型即可改变 {@code data} 字段的类型, 达到重用 {@link GankBaseResponse}
23 | *
24 | * Created by Vea on 26/09/2016 15:19
25 | * ================================================
26 | */
27 | public class GankBaseResponse {
28 | private boolean error;
29 | private T results;
30 |
31 | public T getResults() {
32 | return results;
33 | }
34 |
35 | public void setResults(T results) {
36 | this.results = results;
37 | }
38 |
39 | public boolean getError() {
40 | return error;
41 | }
42 |
43 | public void setError(boolean error) {
44 | this.error = error;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/model/entity/GankItemBean.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.model.entity;
17 |
18 | /**
19 | * ================================================
20 | * Created by Vea on 08/05/2016 12:05
21 | * ================================================
22 | */
23 | public class GankItemBean {
24 | /**
25 | * _id : 57b64b6d421aa93a804bea26
26 | * createdAt : 2016-08-19T07:57:33.576Z
27 | * desc : 8-19
28 | * publishedAt : 2016-08-19T11:26:30.163Z
29 | * source : chrome
30 | * type : 福利
31 | * url : http://ww4.sinaimg.cn/large/610dc034jw1f6yq5xrdofj20u00u0aby.jpg
32 | * used : true
33 | * who : daimajia
34 | */
35 | private String _id;
36 | private String createdAt;
37 | private String desc;
38 | private String publishedAt;
39 | private String source;
40 | private String type;
41 | private String url;
42 | private boolean used;
43 | private String who;
44 | private int height;
45 |
46 | public int getHeight() {
47 | return height;
48 | }
49 |
50 | public void setHeight(int height) {
51 | this.height = height;
52 | }
53 |
54 | public String get_id() {
55 | return _id;
56 | }
57 |
58 | public void set_id(String _id) {
59 | this._id = _id;
60 | }
61 |
62 | public String getCreatedAt() {
63 | return createdAt;
64 | }
65 |
66 | public void setCreatedAt(String createdAt) {
67 | this.createdAt = createdAt;
68 | }
69 |
70 | public String getDesc() {
71 | return desc;
72 | }
73 |
74 | public void setDesc(String desc) {
75 | this.desc = desc;
76 | }
77 |
78 | public String getPublishedAt() {
79 | return publishedAt;
80 | }
81 |
82 | public void setPublishedAt(String publishedAt) {
83 | this.publishedAt = publishedAt;
84 | }
85 |
86 | public String getSource() {
87 | return source;
88 | }
89 |
90 | public void setSource(String source) {
91 | this.source = source;
92 | }
93 |
94 | public String getType() {
95 | return type;
96 | }
97 |
98 | public void setType(String type) {
99 | this.type = type;
100 | }
101 |
102 | public String getUrl() {
103 | return url;
104 | }
105 |
106 | public void setUrl(String url) {
107 | this.url = url;
108 | }
109 |
110 | public boolean isUsed() {
111 | return used;
112 | }
113 |
114 | public void setUsed(boolean used) {
115 | this.used = used;
116 | }
117 |
118 | public String getWho() {
119 | return who;
120 | }
121 |
122 | public void setWho(String who) {
123 | this.who = who;
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/model/service/GankService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.model.service;
17 |
18 | import com.vea.atoms.mvp.gank.mvp.model.entity.GankBaseResponse;
19 | import com.vea.atoms.mvp.gank.mvp.model.entity.GankItemBean;
20 |
21 | import java.util.List;
22 |
23 | import io.reactivex.Observable;
24 | import retrofit2.Retrofit;
25 | import retrofit2.http.GET;
26 | import retrofit2.http.Headers;
27 | import retrofit2.http.Path;
28 |
29 | import static me.jessyan.retrofiturlmanager.RetrofitUrlManager.DOMAIN_NAME_HEADER;
30 |
31 | /**
32 | * ================================================
33 | * 展示 {@link Retrofit#create(Class)} 中需要传入的 ApiService 的使用方式
34 | * 存放关于 gank 的一些 API
35 | *
36 | * Created by Vea on 2016/11/30
37 | * ================================================
38 | */
39 | public interface GankService {
40 |
41 | String GANK_DOMAIN_NAME = "gank";
42 | String GANK_DOMAIN = "http://gank.io";
43 |
44 | /**
45 | * 福利
46 | */
47 | @Headers({DOMAIN_NAME_HEADER + GANK_DOMAIN_NAME})
48 | @GET("/api/data/福利/{num}/{page}")
49 | Observable>> getTechList(@Path("num") int num, @Path("page") int page);
50 | }
51 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/presenter/GirlPresenter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.presenter;
17 |
18 | import com.vea.atoms.mvp.base.BasePresenter;
19 | import com.vea.atoms.mvp.commonsdk.adapter.ShowItemList;
20 | import com.vea.atoms.mvp.gank.mvp.contract.GirlContract;
21 | import com.vea.atoms.mvp.gank.mvp.model.entity.GankBaseResponse;
22 | import com.vea.atoms.mvp.gank.mvp.model.entity.GankItemBean;
23 | import com.vea.atoms.mvp.gank.mvp.model.service.GankService;
24 | import com.vea.atoms.mvp.gank.mvp.ui.fragment.GirlFragment;
25 | import com.vea.atoms.mvp.integration.IRepositoryManager;
26 |
27 | import java.util.List;
28 |
29 | import javax.inject.Inject;
30 |
31 | import io.reactivex.Observer;
32 | import io.reactivex.android.schedulers.AndroidSchedulers;
33 | import io.reactivex.disposables.Disposable;
34 | import io.reactivex.schedulers.Schedulers;
35 | import timber.log.Timber;
36 |
37 | /**
38 | * ================================================
39 | *
40 | * @see GirlFragment
41 | * Created by Vea on 2016/11/24
42 | * ================================================
43 | */
44 | public class GirlPresenter extends BasePresenter implements GirlContract.Presenter {
45 |
46 | private int mCurrentPager = 1;
47 |
48 | private IRepositoryManager repositoryManager;
49 |
50 | @Inject
51 | public GirlPresenter(IRepositoryManager repositoryManager, GirlContract.View view) {
52 | super(view);
53 | this.repositoryManager = repositoryManager;
54 | }
55 |
56 | @Override
57 | public void getGankData(boolean isRefresh) {
58 |
59 | if (isRefresh) {
60 | mCurrentPager = 1;
61 | } else {
62 | mCurrentPager++;
63 | }
64 |
65 | repositoryManager.obtainRetrofitService(GankService.class)
66 | .getTechList(ShowItemList.NUM_OF_PAGE, mCurrentPager)
67 | .subscribeOn(Schedulers.io())
68 | .doOnSubscribe(disposable -> {
69 |
70 | }).subscribeOn(AndroidSchedulers.mainThread())
71 | .observeOn(AndroidSchedulers.mainThread())
72 | .doFinally(() -> {
73 |
74 | }).subscribe(new Observer>>() {
75 | @Override
76 | public void onSubscribe(Disposable d) {
77 | addSubscription(d);
78 | }
79 |
80 | @Override
81 | public void onNext(GankBaseResponse> data) {
82 | if (!data.getError()) {
83 | getView().getGankDataSuccess(data.getResults(), isRefresh);
84 | }
85 | }
86 |
87 | @Override
88 | public void onError(Throwable e) {
89 | Timber.e(e);
90 | getView().getGankDataFailure(isRefresh);
91 | }
92 |
93 | @Override
94 | public void onComplete() {
95 |
96 | }
97 | });
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/ui/activity/GankMainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.ui.activity;
17 |
18 | import android.os.Bundle;
19 | import android.support.annotation.Nullable;
20 | import android.support.design.widget.TabLayout;
21 | import android.support.v4.view.ViewPager;
22 |
23 | import com.alibaba.android.arouter.facade.annotation.Autowired;
24 | import com.alibaba.android.arouter.facade.annotation.Route;
25 | import com.alibaba.android.arouter.launcher.ARouter;
26 | import com.vea.atoms.mvp.base.BaseActivity;
27 | import com.vea.atoms.mvp.commonsdk.adapter.ViewPagerAdapterFragment;
28 | import com.vea.atoms.mvp.commonsdk.core.RouterHub;
29 | import com.vea.atoms.mvp.gank.R;
30 | import com.vea.atoms.mvp.gank.R2;
31 | import com.vea.atoms.mvp.gank.mvp.ui.fragment.GirlFragment;
32 |
33 | import org.vea.atoms.mvp.commonservice.IUserService;
34 |
35 | import butterknife.BindView;
36 | import timber.log.Timber;
37 |
38 | /**
39 | * ================================================
40 | * 承载{@link GirlFragment}
41 | *
42 | * Created by Vea on 2016/11/24
43 | * ================================================
44 | */
45 | @Route(path = RouterHub.GANK_MAIN_ACTIVITY)
46 | public class GankMainActivity extends BaseActivity {
47 |
48 | private ViewPagerAdapterFragment mAdapter;
49 | @BindView(R2.id.tab)
50 | TabLayout tablayout;
51 | @BindView(R2.id.viewpager)
52 | ViewPager viewpager;
53 |
54 | @Autowired
55 | IUserService obj;
56 |
57 | @Override
58 | protected int getLayoutId() {
59 | return R.layout.gank_activity_main;
60 | }
61 |
62 | @Override
63 | protected void initData(@Nullable Bundle savedInstanceState) {
64 | ARouter.getInstance().inject(this);
65 |
66 | mAdapter = new ViewPagerAdapterFragment(getSupportFragmentManager(), this);
67 | mAdapter.addTab("福利", "tag", GirlFragment.class, null);
68 | viewpager.setAdapter(mAdapter);
69 | tablayout.setupWithViewPager(viewpager);
70 |
71 |
72 | // 打印组件的数据传递
73 | if (obj != null) {
74 | Timber.d("--------id:" + obj.getId() + "----------AvatarUrl:" + obj.getAvatarUrl() + "----------Login:" + obj.getLogin());
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/ui/adapter/GirlListAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.ui.adapter;
17 |
18 | import android.content.Context;
19 | import android.support.v7.widget.RecyclerView;
20 | import android.view.LayoutInflater;
21 | import android.view.View;
22 | import android.view.ViewGroup;
23 | import android.widget.ImageView;
24 |
25 | import com.vea.atoms.mvp.commonsdk.adapter.BaseRecyclerAdapter;
26 | import com.vea.atoms.mvp.commonsdk.utils.ImageLoader;
27 | import com.vea.atoms.mvp.gank.R;
28 | import com.vea.atoms.mvp.gank.R2;
29 | import com.vea.atoms.mvp.gank.mvp.model.entity.GankItemBean;
30 |
31 | import butterknife.BindView;
32 | import butterknife.ButterKnife;
33 |
34 |
35 | /**
36 | * ================================================
37 | * Created by Vea on 2016/11/24
38 | * ================================================
39 | */
40 | public class GirlListAdapter extends BaseRecyclerAdapter {
41 |
42 | public GirlListAdapter(Context context) {
43 | super(context, ONLY_FOOTER);
44 | }
45 |
46 | @Override
47 | protected RecyclerView.ViewHolder onCreateDefaultViewHolder(ViewGroup parent, int type) {
48 | return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.gank_item_girl, parent, false));
49 | }
50 |
51 | @Override
52 | protected void onBindDefaultViewHolder(RecyclerView.ViewHolder holder, GankItemBean item, int position) {
53 | ViewHolder h = (ViewHolder) holder;
54 | ImageLoader.load(mContext, h.image, item.getUrl());
55 | }
56 |
57 | public static class ViewHolder extends RecyclerView.ViewHolder {
58 |
59 | @BindView(R2.id.iv_girl)
60 | ImageView image;
61 |
62 | public ViewHolder(View itemView) {
63 | super(itemView);
64 | ButterKnife.bind(this, itemView);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Module-gank/src/main/java/com/vea/atoms/mvp/gank/mvp/ui/fragment/GirlFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.gank.mvp.ui.fragment;
17 |
18 | import android.app.Activity;
19 | import android.os.Bundle;
20 | import android.support.annotation.Nullable;
21 | import android.support.v7.widget.GridLayoutManager;
22 | import android.support.v7.widget.RecyclerView;
23 |
24 | import com.vea.atoms.mvp.base.BaseFragment;
25 | import com.vea.atoms.mvp.commonsdk.adapter.BaseRecyclerAdapter;
26 | import com.vea.atoms.mvp.commonsdk.adapter.IBaseShowItemList;
27 | import com.vea.atoms.mvp.commonsdk.adapter.ListFactory;
28 | import com.vea.atoms.mvp.commonsdk.adapter.RecyclerRefreshLayout;
29 | import com.vea.atoms.mvp.di.component.AppComponent;
30 | import com.vea.atoms.mvp.gank.R;
31 | import com.vea.atoms.mvp.gank.R2;
32 | import com.vea.atoms.mvp.gank.di.component.DaggerGankComponent;
33 | import com.vea.atoms.mvp.gank.mvp.contract.GirlContract;
34 | import com.vea.atoms.mvp.gank.mvp.model.entity.GankItemBean;
35 | import com.vea.atoms.mvp.gank.mvp.presenter.GirlPresenter;
36 | import com.vea.atoms.mvp.gank.mvp.ui.adapter.GirlListAdapter;
37 | import com.vea.atoms.mvp.utils.AtomsUtils;
38 |
39 | import java.util.List;
40 |
41 | import javax.inject.Inject;
42 |
43 | import butterknife.BindView;
44 |
45 | /**
46 | * ================================================
47 | * 福利图片
48 | *
49 | * Created by Vea on 2016/11/24
50 | * ================================================
51 | */
52 | public class GirlFragment extends BaseFragment implements GirlContract.View, RecyclerRefreshLayout.SuperRefreshLayoutListener {
53 |
54 | @Inject
55 | GirlListAdapter adapter;
56 |
57 |
58 | // 如果不是必须要使用还可以使用Lzay
59 | // @Inject
60 | // Lazy adapter;
61 |
62 | @BindView(R2.id.recycler_view)
63 | RecyclerView recyclerView;
64 | @BindView(R2.id.swipe_refresh)
65 | RecyclerRefreshLayout refreshLayout;
66 |
67 | private IBaseShowItemList baseShowItemList;
68 |
69 | @Override
70 | protected void setupFragmentComponent(AppComponent appComponent) {
71 |
72 | DaggerGankComponent
73 | .builder()
74 | .appComponent(appComponent)
75 | .view(this)
76 | .build()
77 | .inject(this);
78 | }
79 |
80 | @Override
81 | protected int getLayoutId() {
82 | return R.layout.gank_fragment_tech;
83 | }
84 |
85 | @Override
86 | protected void initData(@Nullable Bundle savedInstanceState) {
87 |
88 | initRecycleView();
89 | initRefreshLayout();
90 | }
91 |
92 | /**
93 | * 初始化RecyclerView
94 | */
95 | private void initRecycleView() {
96 |
97 | AtomsUtils.configRecyclerView(recyclerView, new GridLayoutManager(getActivity(), 2));
98 | recyclerView.setAdapter(adapter);
99 | }
100 |
101 | /**
102 | * 初始化下拉刷新加载更多
103 | */
104 | private void initRefreshLayout() {
105 | refreshLayout.setSuperRefreshLayoutListener(this);
106 | refreshLayout.post(() -> {
107 | refreshLayout.setRefreshing(true);
108 | onRefreshing();
109 | });
110 | }
111 |
112 | @Override
113 | public void getGankDataSuccess(List mList, boolean isRefresh) {
114 | if (baseShowItemList == null) {
115 | baseShowItemList = new ListFactory().createShowItemList(adapter, refreshLayout);
116 | }
117 | baseShowItemList.showData(isRefresh, mList);
118 | }
119 |
120 | @Override
121 | public void getGankDataFailure(boolean isRefresh) {
122 | refreshLayout.setRefreshing(false);
123 | if (isRefresh) {
124 | AtomsUtils.makeText(getActivity(), "刷新失败");
125 | } else {
126 | adapter.setState(BaseRecyclerAdapter.STATE_LOAD_ERROR, true);
127 | }
128 | }
129 |
130 | @Override
131 | public void onRefreshing() {
132 | mPresenter.getGankData(true);
133 | }
134 |
135 | @Override
136 | public void onLoadMore() {
137 | mPresenter.getGankData(false);
138 | }
139 |
140 | @Override
141 | public Activity getFragmentActivity() {
142 | return getActivity();
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/Module-gank/src/main/res/layout/gank_activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
16 |
17 |
22 |
--------------------------------------------------------------------------------
/Module-gank/src/main/res/layout/gank_fragment_tech.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Module-gank/src/main/res/layout/gank_item_girl.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Module-gank/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Module-gank
3 |
4 |
--------------------------------------------------------------------------------
/Module-gank/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/Module-gank/src/test/java/com/vea/atoms/mvp/gank/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.gank;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 | ### 公众号
5 |
6 |
7 | ## License
8 | ```
9 | Copyright 2018, Vea
10 |
11 | Licensed under the Apache License, Version 2.0 (the "License");
12 | you may not use this file except in compliance with the License.
13 | You may obtain a copy of the License at
14 |
15 | http://www.apache.org/licenses/LICENSE-2.0
16 |
17 | Unless required by applicable law or agreed to in writing, software
18 | distributed under the License is distributed on an "AS IS" BASIS,
19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | See the License for the specific language governing permissions and
21 | limitations under the License.
22 | ```
23 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
6 | defaultConfig {
7 | applicationId "com.vea.atoms.mvp.demo"
8 | minSdkVersion rootProject.ext.android["minSdkVersion"]
9 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
10 | versionCode Integer.parseInt(APP_CODE)
11 | versionName APP_VERSION
12 | javaCompileOptions {
13 | annotationProcessorOptions {
14 | arguments = [moduleName: project.getName()]
15 | includeCompileClasspath true
16 | }
17 | }
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | lintOptions {
27 | disable 'InvalidPackage'
28 | disable "ResourceType"
29 | abortOnError false
30 | }
31 |
32 | compileOptions {
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | sourceCompatibility JavaVersion.VERSION_1_8
35 | }
36 | }
37 |
38 | dependencies {
39 | implementation fileTree(include: ['*.jar'], dir: 'libs')
40 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
41 |
42 | // 使用 runtimeOnly 依赖业务组件, 可实现业务组件的代码在编译时对宿主 App 不可见
43 | if (!isRunGankModule.toBoolean()) {
44 | runtimeOnly project(':Module-gank')
45 | }
46 |
47 |
48 |
49 | implementation project(':CommonSDK')
50 | implementation project(":CommonService")
51 | implementation rootProject.ext.dependencies["swipeback"]
52 | annotationProcessor rootProject.ext.dependencies["dagger2-compiler"]
53 | annotationProcessor rootProject.ext.dependencies["arouter-compiler"]
54 | annotationProcessor rootProject.ext.dependencies["butterknife-compiler"]
55 |
56 | debugImplementation rootProject.ext.dependencies["canary-debug"]
57 | releaseImplementation rootProject.ext.dependencies["canary-release"]
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/org/vea/atoms/mvp/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package org.vea.atoms.mvp;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("org.vea.atoms.mvp", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
15 |
21 |
24 |
27 |
28 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/app/AppLifecyclesImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.demo.app;
17 |
18 | import android.app.Application;
19 | import android.content.Context;
20 | import android.support.annotation.NonNull;
21 |
22 | import com.from.view.swipeback.SwipeBackHelper;
23 | import com.squareup.leakcanary.LeakCanary;
24 | import com.vea.atoms.mvp.app.AppLifecycles;
25 |
26 | /**
27 | * ================================================
28 | * 展示 {@link AppLifecycles} 的用法
29 | *
30 | * Created by Vea on 04/09/2017 17:12
31 | * ================================================
32 | */
33 | public class AppLifecyclesImpl implements AppLifecycles {
34 |
35 | @Override
36 | public void attachBaseContext(@NonNull Application application, @NonNull Context base) {
37 | // MultiDex.install(base); //这里比 onCreate 先执行,常用于 MultiDex 初始化,插件化框架的初始化
38 | }
39 |
40 | @Override
41 | public void onCreate(@NonNull Application application) {
42 | if (LeakCanary.isInAnalyzerProcess(application)) {
43 | // This process is dedicated to LeakCanary for heap analysis.
44 | // You should not init your app in this process.
45 | return;
46 | }
47 |
48 | LeakCanary.install(application);
49 | // 一键侧滑返回
50 | SwipeBackHelper.init(application);
51 |
52 | }
53 |
54 | @Override
55 | public void onTerminate(@NonNull Application application) {
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/app/GlobalConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.demo.app;
17 |
18 | import android.content.Context;
19 |
20 | import com.vea.atoms.mvp.app.AppDelegate;
21 | import com.vea.atoms.mvp.app.AppLifecycles;
22 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
23 | import com.vea.atoms.mvp.integration.ConfigModule;
24 | import com.vea.atoms.mvp.integration.ManifestParser;
25 |
26 | import java.util.List;
27 |
28 |
29 | /**
30 | * ================================================
31 | * App 的全局配置信息在此配置, 需要将此实现类声明到 AndroidManifest 中
32 | * ConfigModule 的实现类可以有无数多个, 在 Application 中只是注册回调, 并不会影响性能 (多个 ConfigModule 在多 Module 环境下尤为受用)
33 | * 不过要注意 ConfigModule 接口的实现类对象是通过反射生成的, 这里会有些性能损耗
34 | *
35 | * @see AppDelegate
36 | * @see ManifestParser
37 | * Created by Vea on 12/04/2017 17:25
38 | * ================================================
39 | */
40 | public final class GlobalConfiguration implements ConfigModule {
41 |
42 | @Override
43 | public void applyOptions(Context context, GlobalConfigModule.Builder builder) {
44 | }
45 |
46 | @Override
47 | public void injectAppLifecycle(Context context, List lifecycles) {
48 | // AppLifecycles 的所有方法都会在基类 Application 的对应的生命周期中被调用,所以在对应的方法中可以扩展一些自己需要的逻辑
49 | // 可以根据不同的逻辑添加多个实现类
50 | lifecycles.add(new AppLifecyclesImpl());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/di/component/DemoComponent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.demo.di.component;
17 |
18 | import com.vea.atoms.mvp.demo.di.module.DemoModule;
19 | import com.vea.atoms.mvp.demo.mvp.ui.MainActivity;
20 | import com.vea.atoms.mvp.di.component.AppComponent;
21 | import com.vea.atoms.mvp.di.scope.ActivityScope;
22 |
23 | import dagger.Component;
24 |
25 | /**
26 | * ================================================
27 | * 展示 Component 的用法
28 | *
29 | * Created by Vea on 09/04/2016 11:17
30 | * ================================================
31 | */
32 | @ActivityScope
33 | @Component(modules = DemoModule.class, dependencies = AppComponent.class)
34 | public interface DemoComponent {
35 |
36 | void inject(MainActivity activity);
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/di/module/DemoModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.demo.di.module;
17 |
18 | import dagger.Module;
19 |
20 | /**
21 | * ================================================
22 | * 展示 Module 的用法
23 | *
24 | * Created by Vea on 09/04/2016 11:10
25 | * ================================================
26 | * e呃呃呃呃呃
27 | */
28 | @Module
29 | public class DemoModule {
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/adapter/ManListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.demo.mvp.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 |
10 | import com.vea.atoms.mvp.commonsdk.adapter.BaseRecyclerAdapter;
11 | import com.vea.atoms.mvp.commonsdk.utils.ImageLoader;
12 | import com.vea.atoms.mvp.demo.R;
13 | import com.vea.atoms.mvp.demo.mvp.model.entity.User;
14 |
15 | import butterknife.BindView;
16 | import butterknife.ButterKnife;
17 |
18 | /**
19 | * ================================================
20 | * Created by Vea on 2018/8/26
21 | * ================================================
22 | */
23 | public class ManListAdapter extends BaseRecyclerAdapter {
24 |
25 | public ManListAdapter(Context context) {
26 | super(context, ONLY_FOOTER);
27 | }
28 |
29 | @Override
30 | protected RecyclerView.ViewHolder onCreateDefaultViewHolder(ViewGroup parent, int type) {
31 | return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_man, parent, false));
32 | }
33 |
34 | @Override
35 | protected void onBindDefaultViewHolder(RecyclerView.ViewHolder holder, User item, int position) {
36 | ViewHolder h = (ViewHolder) holder;
37 | ImageLoader.load(mContext, h.image, item.getAvatarUrl());
38 | }
39 |
40 | public static class ViewHolder extends RecyclerView.ViewHolder {
41 |
42 | @BindView(R.id.iv_girl)
43 | ImageView image;
44 |
45 | public ViewHolder(View itemView) {
46 | super(itemView);
47 | ButterKnife.bind(this, itemView);
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/contract/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.demo.mvp.contract;
2 |
3 | import com.vea.atoms.mvp.base.IPresenter;
4 | import com.vea.atoms.mvp.base.IView;
5 | import com.vea.atoms.mvp.demo.mvp.model.entity.User;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by vea on 2018/8/24.
11 | */
12 |
13 | public interface MainContract {
14 |
15 |
16 | interface View extends IView {
17 |
18 | void getUserSuccess(List users, boolean isRefresh);
19 |
20 | void getUserFailure(boolean isRefresh);
21 | }
22 |
23 | interface Presenter extends IPresenter {
24 |
25 | void getUser(int lastIdQueried, boolean isRefresh);
26 | }
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/model/entity/BaseResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.demo.mvp.model.entity;
17 |
18 | import com.vea.atoms.mvp.demo.mvp.model.service.DemoService;
19 |
20 | import java.io.Serializable;
21 |
22 | /**
23 | * ================================================
24 | * 如果你服务器返回的数据格式固定为这种方式(这里只提供思想,服务器返回的数据格式可能不一致,可根据自家服务器返回的格式作更改)
25 | * 指定范型即可改变 {@code data} 字段的类型, 达到重用 {@link BaseResponse}, 如果你实在看不懂, 请忽略
26 | *
27 | * Created by Vea on 26/09/2016 15:19
28 | * ================================================
29 | */
30 | public class BaseResponse implements Serializable {
31 | private T data;
32 | private String code;
33 | private String msg;
34 |
35 | public T getData() {
36 | return data;
37 | }
38 |
39 | public String getCode() {
40 | return code;
41 | }
42 |
43 | public String getMsg() {
44 | return msg;
45 | }
46 |
47 | /**
48 | * 请求是否成功
49 | *
50 | * @return
51 | */
52 | public boolean isSuccess() {
53 | if (code.equals(DemoService.RequestSuccess)) {
54 | return true;
55 | } else {
56 | return false;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/model/entity/User.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.demo.mvp.model.entity;
17 |
18 |
19 | import org.vea.atoms.mvp.commonservice.IUserService;
20 |
21 | /**
22 | * ================================================
23 | * User 实体类
24 | *
25 | * Created by Vea on 04/09/2016 17:14
26 | * ================================================
27 | */
28 | public class User implements IUserService {
29 |
30 | private int id;
31 | private String login;
32 | private String avatar_url;
33 |
34 |
35 | public void setId(int id) {
36 | this.id = id;
37 | }
38 |
39 | public void setLogin(String login) {
40 | this.login = login;
41 | }
42 |
43 | @Override
44 | public String getAvatarUrl() {
45 | return avatar_url;
46 | }
47 |
48 | @Override
49 | public int getId() {
50 | return id;
51 | }
52 |
53 | @Override
54 | public String getLogin() {
55 | return login;
56 | }
57 |
58 | @Override
59 | public void setAvatarUrl(String avatar_url) {
60 | this.avatar_url = avatar_url;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/model/service/DemoService.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.demo.mvp.model.service;
2 |
3 | import com.vea.atoms.mvp.demo.mvp.model.entity.User;
4 |
5 | import java.util.List;
6 |
7 | import io.reactivex.Observable;
8 | import retrofit2.http.GET;
9 | import retrofit2.http.Headers;
10 | import retrofit2.http.Query;
11 |
12 |
13 | /**
14 | * ================================================
15 | * 服务端Api相关接口定义
16 | *
17 | * Created by Vea on 2018/8/23.
18 | * ================================================
19 | */
20 | public interface DemoService {
21 |
22 | String APP_DOMAIN = "https://api.github.com";
23 | String RequestSuccess = "0";
24 |
25 |
26 | String HEADER_API_VERSION = "Accept: application/vnd.github.v3+json";
27 |
28 | @Headers({HEADER_API_VERSION})
29 | @GET("/users")
30 | Observable> getUsers(@Query("since") int lastIdQueried, @Query("per_page") int perPage);
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.demo.mvp.presenter;
2 |
3 | import com.vea.atoms.mvp.base.BasePresenter;
4 | import com.vea.atoms.mvp.commonsdk.adapter.ShowItemList;
5 | import com.vea.atoms.mvp.demo.mvp.contract.MainContract;
6 | import com.vea.atoms.mvp.demo.mvp.model.entity.User;
7 | import com.vea.atoms.mvp.demo.mvp.model.service.DemoService;
8 | import com.vea.atoms.mvp.integration.IRepositoryManager;
9 |
10 | import java.util.List;
11 |
12 | import javax.inject.Inject;
13 |
14 | import io.reactivex.Observer;
15 | import io.reactivex.android.schedulers.AndroidSchedulers;
16 | import io.reactivex.disposables.Disposable;
17 | import io.reactivex.schedulers.Schedulers;
18 | import timber.log.Timber;
19 |
20 | /**
21 | * ================================================
22 | * 首页 Presenter
23 | *
24 | * Created by Vea on 2018/8/23.
25 | * ================================================
26 | */
27 | public class MainPresenter extends BasePresenter implements MainContract.Presenter {
28 |
29 | private IRepositoryManager repositoryManager;
30 |
31 | @Inject
32 | public MainPresenter(IRepositoryManager repositoryManager) {
33 | this.repositoryManager = repositoryManager;
34 | }
35 |
36 | @Override
37 | public void getUser(int lastIdQueried, boolean isRefresh) {
38 |
39 | repositoryManager.obtainRetrofitService(DemoService.class)
40 | .getUsers(lastIdQueried, ShowItemList.NUM_OF_PAGE)
41 | .subscribeOn(Schedulers.io())
42 | .doOnSubscribe(disposable -> {
43 | // 订阅之前常用于显示loading
44 | // TODO
45 | }).subscribeOn(AndroidSchedulers.mainThread())
46 | .observeOn(AndroidSchedulers.mainThread()) // 在主线程中回调订阅事件
47 | .doFinally(() -> {
48 | // 结束之后隐藏LoadingView
49 | })
50 | .subscribe(new Observer>() {
51 | @Override
52 | public void onSubscribe(Disposable d) {
53 | addSubscription(d);
54 | }
55 |
56 | @Override
57 | public void onNext(List users) {
58 | getView().getUserSuccess(users, isRefresh);
59 | }
60 |
61 | @Override
62 | public void onError(Throwable e) {
63 | Timber.d(e);
64 | getView().getUserFailure(isRefresh);
65 | }
66 |
67 | @Override
68 | public void onComplete() {
69 |
70 | }
71 | });
72 |
73 | }
74 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/ui/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.demo.mvp.ui;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.widget.GridLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.view.View;
8 | import android.widget.ImageView;
9 |
10 | import com.alibaba.android.arouter.facade.annotation.Route;
11 | import com.alibaba.android.arouter.launcher.ARouter;
12 | import com.vea.atoms.mvp.base.BaseActivity;
13 | import com.vea.atoms.mvp.commonsdk.adapter.BaseRecyclerAdapter;
14 | import com.vea.atoms.mvp.commonsdk.adapter.IBaseShowItemList;
15 | import com.vea.atoms.mvp.commonsdk.adapter.ListFactory;
16 | import com.vea.atoms.mvp.commonsdk.adapter.RecyclerRefreshLayout;
17 | import com.vea.atoms.mvp.commonsdk.core.RouterHub;
18 | import com.vea.atoms.mvp.demo.R;
19 | import com.vea.atoms.mvp.demo.di.component.DaggerDemoComponent;
20 | import com.vea.atoms.mvp.demo.mvp.adapter.ManListAdapter;
21 | import com.vea.atoms.mvp.demo.mvp.contract.MainContract;
22 | import com.vea.atoms.mvp.demo.mvp.model.entity.User;
23 | import com.vea.atoms.mvp.demo.mvp.presenter.MainPresenter;
24 | import com.vea.atoms.mvp.di.component.AppComponent;
25 | import com.vea.atoms.mvp.utils.AtomsUtils;
26 |
27 | import java.util.List;
28 |
29 | import butterknife.BindView;
30 | import butterknife.OnClick;
31 |
32 | /**
33 | * ================================================
34 | * 首页Activity,展示图片
35 | *
36 | * Created by Vea on 2018/8/23.
37 | * ================================================
38 | */
39 | @Route(path = RouterHub.APP_MAIN_ACTIVITY)
40 | public class MainActivity extends BaseActivity implements MainContract.View, RecyclerRefreshLayout.SuperRefreshLayoutListener {
41 |
42 | private ManListAdapter adapter;
43 |
44 | private IBaseShowItemList baseShowItemList;
45 |
46 | @BindView(R.id.recycler_view)
47 | RecyclerView recyclerView;
48 | @BindView(R.id.swipe_refresh)
49 | RecyclerRefreshLayout refreshLayout;
50 |
51 | @BindView(R.id.image_mouth)
52 | ImageView imageMouth;
53 |
54 | @Override
55 | protected void setupActivityComponent(AppComponent appComponent) {
56 | DaggerDemoComponent
57 | .builder()
58 | .appComponent(appComponent)
59 | .build()
60 | .inject(this);
61 | }
62 |
63 | @Override
64 | protected int getLayoutId() {
65 | return R.layout.activity_main;
66 | }
67 |
68 | @Override
69 | protected void initData(@Nullable Bundle savedInstanceState) {
70 | ARouter.getInstance().inject(this);
71 |
72 | initRecycleView();
73 | initRefreshLayout();
74 | }
75 |
76 | /**
77 | * 初始化下拉刷新加载更多
78 | */
79 | private void initRefreshLayout() {
80 | refreshLayout.setSuperRefreshLayoutListener(this);
81 | refreshLayout.post(() -> {
82 | refreshLayout.setRefreshing(true);
83 | onRefreshing();
84 | });
85 | }
86 |
87 | /**
88 | * 初始化RecyclerView
89 | */
90 | private void initRecycleView() {
91 | adapter = new ManListAdapter(this);
92 | adapter.setState(BaseRecyclerAdapter.STATE_HIDE, false);
93 |
94 | AtomsUtils.configRecyclerView(recyclerView, new GridLayoutManager(this, 2));
95 | recyclerView.setAdapter(adapter);
96 | }
97 |
98 | @Override
99 | public void getUserSuccess(List users, boolean isRefresh) {
100 | if (users != null && users.size() > 0) {
101 | if (baseShowItemList == null) {
102 | baseShowItemList = new ListFactory().createShowItemList(adapter, refreshLayout);
103 | }
104 | baseShowItemList.showData(isRefresh, users);
105 | }
106 | }
107 |
108 | @Override
109 | public void getUserFailure(boolean isRefresh) {
110 | refreshLayout.setRefreshing(false);
111 | if (isRefresh) {
112 | AtomsUtils.makeText(this, "刷新失败");
113 | } else {
114 | adapter.setState(BaseRecyclerAdapter.STATE_LOAD_ERROR, true);
115 | }
116 | }
117 |
118 | @Override
119 | public void onRefreshing() {
120 | mPresenter.getUser(1, true);
121 | }
122 |
123 | @Override
124 | public void onLoadMore() {
125 | // 总size-1 再减去底布局-1
126 | int id = adapter.getItem(adapter.getItemCount() - 1 - 1).getId();
127 | mPresenter.getUser(id, false);
128 | }
129 |
130 | @OnClick({R.id.image_mouth})
131 | public void onViewClicked(View view) {
132 | switch (view.getId()) {
133 | case R.id.image_mouth:
134 | if (adapter.getItems() != null && adapter.getItems().size() > 10) {
135 |
136 | /**
137 | * 展示组件之间数据传递
138 | * 一般情况下并不需要传递整个user对象,如果只需要某个key,name
139 | * 只需设置withString(k,v)即可。 传递对象可使用withObject
140 | */
141 | User item = adapter.getItem(0);
142 | ARouter.getInstance()
143 | .build(RouterHub.GANK_MAIN_ACTIVITY)
144 | .withObject("obj", item)
145 | .navigation();
146 | }
147 | break;
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/mvp/ui/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.demo.mvp.ui;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.support.v7.app.AppCompatActivity;
6 |
7 | import com.alibaba.android.arouter.launcher.ARouter;
8 | import com.vea.atoms.mvp.commonsdk.core.RouterHub;
9 |
10 | public class SplashActivity extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | // setContentView(R.layout.activity_splash);
16 |
17 | new Handler().postDelayed(new Runnable() {
18 | @Override
19 | public void run() {
20 | ARouter.getInstance().build(RouterHub.APP_MAIN_ACTIVITY).navigation();
21 | finish();
22 | }
23 | }, 1000);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vea/atoms/mvp/demo/utils/JsonServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.demo.utils;
2 |
3 | import android.content.Context;
4 |
5 | import com.alibaba.android.arouter.facade.annotation.Route;
6 | import com.alibaba.android.arouter.facade.service.SerializationService;
7 | import com.alibaba.fastjson.JSON;
8 |
9 | import java.lang.reflect.Type;
10 |
11 | /**
12 | * Used for json converter
13 | *
14 | * @author zhilong Contact me.
15 | * @version 1.0
16 | * @since 2017/4/10 下午2:10
17 | */
18 | @Route(path = "/service/json")
19 | public class JsonServiceImpl implements SerializationService {
20 | @Override
21 | public void init(Context context) {
22 |
23 | }
24 |
25 | @Override
26 | public T json2Object(String text, Class clazz) {
27 | return JSON.parseObject(text, clazz);
28 | }
29 |
30 | @Override
31 | public String object2Json(Object instance) {
32 | return JSON.toJSONString(instance);
33 | }
34 |
35 | @Override
36 | public T parseObject(String input, Type clazz) {
37 | return JSON.parseObject(input, clazz);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/layer_splash_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
12 |
13 |
20 |
21 |
22 |
29 |
30 |
31 |
32 |
33 |
34 |
39 |
40 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_man.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_girl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xhdpi/ic_girl.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/splash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/app/src/main/res/mipmap-xxxhdpi/splash_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #663366
4 | #663366
5 | #FF4081
6 | #333333
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MVPAtoms
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/org/vea/atoms/mvp/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package org.vea.atoms.mvp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/atoms/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/atoms/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
6 |
7 | defaultConfig {
8 | minSdkVersion rootProject.ext.android["minSdkVersion"]
9 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
10 | versionCode 1
11 | versionName APP_VERSION
12 | }
13 |
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 |
21 | compileOptions {
22 | targetCompatibility JavaVersion.VERSION_1_8
23 | sourceCompatibility JavaVersion.VERSION_1_8
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 |
30 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
31 | def appDependencies = rootProject.ext.dependencies
32 |
33 | api rootProject.ext.dependencies["appcompat-v7"]
34 | api rootProject.ext.dependencies["design"]
35 | api rootProject.ext.dependencies["support-v4"]
36 | api rootProject.ext.dependencies["recyclerview-v7"]
37 | api rootProject.ext.dependencies["cardview-v7"]
38 | api rootProject.ext.dependencies["constraintLayout"]
39 |
40 | api rootProject.ext.dependencies["rxjava2"]
41 | api rootProject.ext.dependencies["rxandroid2"]
42 | api rootProject.ext.dependencies["retrofit"]
43 | api rootProject.ext.dependencies["retrofit-converter-gson"]
44 | api rootProject.ext.dependencies["retrofit-adapter-rxjava2"]
45 |
46 | api rootProject.ext.dependencies["butterknife"]
47 |
48 | api rootProject.ext.dependencies["dagger2"]
49 | annotationProcessor rootProject.ext.dependencies["dagger2-compiler"]
50 |
51 | api rootProject.ext.dependencies["timber"]
52 | api rootProject.ext.dependencies["multidex"]
53 | api appDependencies["androideventbus"]
54 | api appDependencies["avi_loading"]
55 | }
56 |
--------------------------------------------------------------------------------
/atoms/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/atoms/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/app/ActivityManager.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.app;
2 |
3 | import android.app.Activity;
4 |
5 | import java.util.Stack;
6 |
7 | /**
8 | * activity堆栈式管理
9 | */
10 | public class ActivityManager {
11 | private static Stack activityStack;
12 | private static ActivityManager instance;
13 |
14 | private ActivityManager() {
15 | }
16 |
17 | /**
18 | * 单一实例
19 | */
20 | public static ActivityManager getAppManager() {
21 | if (instance == null) {
22 | instance = new ActivityManager();
23 | }
24 |
25 | if (activityStack == null) {
26 | activityStack = new Stack();
27 | }
28 |
29 | return instance;
30 | }
31 |
32 | /**
33 | * 获取指定的Activity
34 | *
35 | * @author kymjs
36 | */
37 | public static Activity getActivity(Class> cls) {
38 | if (activityStack != null)
39 | for (Activity activity : activityStack) {
40 | if (activity.getClass().equals(cls)) {
41 | return activity;
42 | }
43 | }
44 | return null;
45 | }
46 |
47 | /**
48 | * 添加Activity到堆栈
49 | */
50 | public void addActivity(Activity activity) {
51 | activityStack.add(activity);
52 | }
53 |
54 | /**
55 | * 获取当前Activity(堆栈中最后一个压入的)
56 | */
57 | public Activity currentActivity() {
58 | Activity activity = activityStack.lastElement();
59 | return activity;
60 | }
61 |
62 | /**
63 | * 结束当前Activity(堆栈中最后一个压入的)
64 | */
65 | public void finishActivity() {
66 | Activity activity = activityStack.lastElement();
67 | finishActivity(activity);
68 | }
69 |
70 | /**
71 | * 结束指定的Activity
72 | */
73 | public void finishActivity(Activity activity) {
74 | if (activity != null && activityStack.contains(activity)) {
75 | activity.finish();
76 | }
77 | }
78 |
79 | /**
80 | * 结束指定的Activity
81 | */
82 | public void removeActivity(Activity activity) {
83 | if (activity != null && activityStack.contains(activity)) {
84 | activityStack.remove(activity);
85 | }
86 | }
87 |
88 | /**
89 | * 结束指定类名的Activity
90 | */
91 | public void finishActivity(Class> cls) {
92 | for (Activity activity : activityStack) {
93 | if (activity.getClass().equals(cls)) {
94 | finishActivity(activity);
95 | break;
96 | }
97 | }
98 | }
99 |
100 | /**
101 | * 结束所有Activity
102 | */
103 | public void finishAllActivity() {
104 | for (int i = 0; i < activityStack.size(); i++) {
105 | if (null != activityStack.get(i)) {
106 | finishActivity(activityStack.get(i));
107 | }
108 | }
109 | activityStack.clear();
110 | }
111 |
112 | /**
113 | * 退出应用程序
114 | */
115 | public void AppExit() {
116 | try {
117 | finishAllActivity();
118 | // System.exit(0);
119 | } catch (Exception e) {
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/app/AppDelegate.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.app;
17 |
18 | import android.app.Application;
19 | import android.content.Context;
20 | import android.support.annotation.NonNull;
21 |
22 | import com.vea.atoms.mvp.di.component.AppComponent;
23 | import com.vea.atoms.mvp.di.component.DaggerAppComponent;
24 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
25 | import com.vea.atoms.mvp.integration.ConfigModule;
26 | import com.vea.atoms.mvp.integration.ManifestParser;
27 | import com.vea.atoms.mvp.utils.AtomsUtils;
28 | import com.vea.atoms.mvp.utils.Preconditions;
29 |
30 | import java.util.ArrayList;
31 | import java.util.List;
32 |
33 | /**
34 | * ================================================
35 | * AppDelegate 可以代理 Application 的生命周期,在对应的生命周期,执行对应的逻辑,因为 Java 只能单继承
36 | * 所以当遇到某些三方库需要继承于它的 Application 的时候,就只有自定义 Application 并继承于三方库的 Application
37 | * 这时就不用再继承 BaseApplication,只用在自定义Application中对应的生命周期调用AppDelegate对应的方法
38 | * (Application一定要实现APP接口),框架就能照常运行
39 | *
40 | * @see BaseApplication
41 | * Created by Vea on 24/04/2017 09:44
42 | * ================================================
43 | */
44 | public class AppDelegate implements IApp, AppLifecycles {
45 |
46 | private Application mApplication;
47 | private AppComponent mAppComponent;
48 |
49 | private List mAppLifecycles = new ArrayList<>();
50 |
51 | private List mModules;
52 |
53 | public AppDelegate(@NonNull Context context) {
54 |
55 | //用反射, 将 AndroidManifest.xml 中带有 ConfigModule 标签的 class 转成对象集合(List)
56 | this.mModules = new ManifestParser(context).parse();
57 |
58 | //遍历之前获得的集合, 执行每一个 ConfigModule 实现类的某些方法
59 | for (ConfigModule module : mModules) {
60 |
61 | //将框架外部, 开发者实现的 Application 的生命周期回调 (AppLifecycles) 存入 mAppLifecycles 集合 (此时还未注册回调)
62 | module.injectAppLifecycle(context, mAppLifecycles);
63 | }
64 | }
65 |
66 | @Override
67 | public void attachBaseContext(@NonNull Application application, @NonNull Context base) {
68 |
69 | //遍历 mAppLifecycles, 执行所有已注册的 AppLifecycles 的 attachBaseContext() 方法 (框架外部, 开发者扩展的逻辑)
70 | for (AppLifecycles lifecycle : mAppLifecycles) {
71 | lifecycle.attachBaseContext(application, base);
72 | }
73 | }
74 |
75 | @Override
76 | public void onCreate(@NonNull Application application) {
77 | this.mApplication = application;
78 | mAppComponent = DaggerAppComponent
79 | .builder()
80 | .application(mApplication)//提供application
81 | .globalConfigModule(getGlobalConfigModule(mApplication, mModules))//全局配置
82 | .build();
83 | mAppComponent.injectDelegate(this);
84 |
85 |
86 | //执行框架外部, 开发者扩展的 App onCreate 逻辑
87 | for (AppLifecycles lifecycle : mAppLifecycles) {
88 | lifecycle.onCreate(mApplication);
89 | }
90 | }
91 |
92 | @Override
93 | public void onTerminate(@NonNull Application application) {
94 |
95 | if (mAppLifecycles != null && mAppLifecycles.size() > 0) {
96 | for (AppLifecycles lifecycle : mAppLifecycles) {
97 | lifecycle.onTerminate(mApplication);
98 | }
99 | }
100 | this.mAppComponent = null;
101 | this.mAppLifecycles = null;
102 | this.mApplication = null;
103 | }
104 |
105 | /**
106 | * 将app的全局配置信息封装进module(使用Dagger注入到需要配置信息的地方)
107 | * 需要在AndroidManifest中声明{@link ConfigModule}的实现类,和Glide的配置方式相似
108 | *
109 | * @return GlobalConfigModule
110 | */
111 | private GlobalConfigModule getGlobalConfigModule(Context context, List modules) {
112 |
113 | GlobalConfigModule.Builder builder = GlobalConfigModule
114 | .builder();
115 |
116 | //遍历 ConfigModule 集合, 给全局配置 GlobalConfigModule 添加参数
117 | for (ConfigModule module : modules) {
118 | module.applyOptions(context, builder);
119 | }
120 |
121 | return builder.build();
122 | }
123 |
124 | /**
125 | * 将 {@link AppComponent} 返回出去, 供其它地方使用, {@link AppComponent} 接口中声明的方法返回的实例, 在 {@link #getAppComponent()} 拿到对象后都可以直接使用
126 | *
127 | * @return AppComponent
128 | * @see AtomsUtils#obtainAppComponentFromContext(Context) 可直接获取 {@link AppComponent}
129 | */
130 | @NonNull
131 | @Override
132 | public AppComponent getAppComponent() {
133 | Preconditions.checkNotNull(mAppComponent,
134 | "%s cannot be null,first call %s#onCreate(Application) in %s#onCreate()",
135 | AppComponent.class.getName(), getClass().getName(), Application.class.getName());
136 | return mAppComponent;
137 | }
138 | }
139 |
140 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/app/AppLifecycles.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.app;
17 |
18 | import android.app.Application;
19 | import android.content.Context;
20 | import android.support.annotation.NonNull;
21 |
22 | /**
23 | * ================================================
24 | * 用于代理 {@link Application} 的生命周期
25 | *
26 | * @see AppDelegate
27 | * Created by Vea on 2018/8/20
28 | * ================================================
29 | */
30 | public interface AppLifecycles {
31 |
32 | /**
33 | * @param application 最初设计上没有这个参数,为了给插件化调用。如何插件化可参考360RePlugin
34 | * @param base Context
35 | */
36 | void attachBaseContext(@NonNull Application application, @NonNull Context base);
37 |
38 | void onCreate(@NonNull Application application);
39 |
40 | void onTerminate(@NonNull Application application);
41 | }
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/app/AppManager.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.app;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * AppManager
11 | *
12 | * @author lishide
13 | * @date 2018/12/12
14 | */
15 | public class AppManager {
16 |
17 | private Application mApplication;
18 |
19 | private List mLogouts;
20 |
21 | public static class AppManagerHolder {
22 | private static AppManager sAppManager = new AppManager();
23 | }
24 |
25 | public static AppManager getInstance() {
26 | return AppManagerHolder.sAppManager;
27 | }
28 |
29 | private AppManager() {
30 | mApplication = initApplication();
31 | }
32 |
33 | public Application getApplication() {
34 | return mApplication;
35 | }
36 |
37 | static Application initApplication() {
38 | try {
39 | //通过反射的方式来获取当前进程的application对象
40 | Application app = (Application) Class.forName("android.app.ActivityThread")
41 | .getMethod("currentApplication").invoke(null);
42 | if (app != null) {
43 | return app;
44 | }
45 | } catch (Exception e) {
46 | e.printStackTrace();
47 | }
48 | try {
49 | Application app = (Application) Class.forName("android.app.AppGlobals")
50 | .getMethod("getInitialApplication").invoke(null);
51 | if (app != null) {
52 | return app;
53 | }
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | }
57 | return null;
58 | }
59 |
60 | public void addLogout(ILogout logout) {
61 | if (mLogouts == null) {
62 | mLogouts = new ArrayList<>();
63 | }
64 |
65 | mLogouts.add(logout);
66 | }
67 |
68 | public void logout(Context context) {
69 | if (mLogouts != null) {
70 | for (ILogout info : mLogouts) {
71 | info.logout(context);
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/app/BaseApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.app;
17 |
18 | import android.app.Activity;
19 | import android.app.Application;
20 | import android.content.Context;
21 | import android.os.Bundle;
22 | import android.support.annotation.NonNull;
23 | import android.support.multidex.MultiDex;
24 |
25 | import com.vea.atoms.mvp.di.component.AppComponent;
26 | import com.vea.atoms.mvp.utils.AtomsUtils;
27 | import com.vea.atoms.mvp.utils.Preconditions;
28 |
29 | import timber.log.Timber;
30 |
31 | /**
32 | * ================================================
33 | * BaseApplication每个模块的Application都使用B
34 | *
35 | * Created by Vea on 2018/8/20
36 | * ================================================
37 | */
38 | public class BaseApplication extends Application implements IApp {
39 |
40 | private AppLifecycles mAppDelegate;
41 |
42 | private ActivityLifecycleCallbacks mActivityLifecycleCallbacks;
43 |
44 | private static BaseApplication mApplication;
45 |
46 | public static BaseApplication getInstance() {
47 | return mApplication;
48 | }
49 |
50 | public static void setApplication(BaseApplication mApplication) {
51 | BaseApplication.mApplication = mApplication;
52 | }
53 |
54 | @Override
55 | protected void attachBaseContext(Context base) {
56 | super.attachBaseContext(base);
57 | MultiDex.install(base);
58 |
59 | if (mAppDelegate == null) {
60 | this.mAppDelegate = new AppDelegate(base);
61 | }
62 | this.mAppDelegate.attachBaseContext(this, base);
63 | }
64 |
65 | @Override
66 | public void onCreate() {
67 | super.onCreate();
68 | setApplication(this);
69 | if (mAppDelegate != null) {
70 | this.mAppDelegate.onCreate(this);
71 | }
72 |
73 | Timber.d("BaseApplication#onCreate");
74 |
75 | mActivityLifecycleCallbacks = new ActivityLifecycleCallbacks() {
76 | @Override
77 | public void onActivityCreated(Activity activity, Bundle bundle) {
78 | ActivityManager.getAppManager().addActivity(activity);
79 | }
80 |
81 | @Override
82 | public void onActivityStarted(Activity activity) {
83 |
84 | }
85 |
86 | @Override
87 | public void onActivityResumed(Activity activity) {
88 |
89 | }
90 |
91 | @Override
92 | public void onActivityPaused(Activity activity) {
93 |
94 | }
95 |
96 | @Override
97 | public void onActivityStopped(Activity activity) {
98 |
99 | }
100 |
101 | @Override
102 | public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
103 |
104 | }
105 |
106 | @Override
107 | public void onActivityDestroyed(Activity activity) {
108 | ActivityManager.getAppManager().removeActivity(activity);
109 | }
110 | };
111 |
112 | registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
113 | }
114 |
115 | /**
116 | * 在模拟环境中程序终止时会被调用
117 | */
118 | @Override
119 | public void onTerminate() {
120 | super.onTerminate();
121 | if (mAppDelegate != null)
122 | this.mAppDelegate.onTerminate(this);
123 | unregisterActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
124 | }
125 |
126 | /**
127 | * 将 {@link AppComponent} 返回出去, 供其它地方使用, {@link AppComponent} 接口中声明的方法所返回的实例, 在 {@link #getAppComponent()} 拿到对象后都可以直接使用
128 | *
129 | * @return AppComponent
130 | * @see AtomsUtils#obtainAppComponentFromContext(Context) 可直接获取 {@link AppComponent}
131 | */
132 | @NonNull
133 | @Override
134 | public AppComponent getAppComponent() {
135 | Preconditions.checkNotNull(mAppDelegate, "%s cannot be null", AppDelegate.class.getName());
136 | Preconditions.checkState(mAppDelegate instanceof IApp, "%s must be implements %s", AppDelegate.class.getName(), IApp.class.getName());
137 | return ((IApp) mAppDelegate).getAppComponent();
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/app/IApp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.app;
17 |
18 | import android.support.annotation.NonNull;
19 |
20 | import com.vea.atoms.mvp.di.component.AppComponent;
21 |
22 |
23 | /**
24 | * ================================================
25 | * 框架要求框架中的每个 {@link android.app.Application} 都需要实现此类, 以满足规范
26 | *
27 | * @see BaseApplication
28 | * Created by Vea on 2018/8/20
29 | * ================================================
30 | */
31 | public interface IApp {
32 |
33 | @NonNull
34 | AppComponent getAppComponent();
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/app/ILogout.java:
--------------------------------------------------------------------------------
1 | package com.vea.atoms.mvp.app;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * ILogout
7 | *
8 | * @author lishide
9 | * @date 2018/12/31
10 | */
11 | public interface ILogout {
12 |
13 |
14 | void logout(Context context);
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.base;
17 |
18 | import android.os.Bundle;
19 | import android.support.annotation.Nullable;
20 | import android.support.v7.app.AppCompatActivity;
21 | import android.view.LayoutInflater;
22 | import android.view.View;
23 | import android.widget.FrameLayout;
24 | import android.widget.Toast;
25 |
26 | import com.vea.atoms.mvp.di.component.AppComponent;
27 | import com.vea.atoms.mvp.utils.AtomsUtils;
28 | import com.wang.avi.AVLoadingIndicatorView;
29 |
30 | import javax.inject.Inject;
31 |
32 | import butterknife.ButterKnife;
33 | import butterknife.Unbinder;
34 |
35 | /**
36 | * ================================================
37 | * MVP activity基类
38 | *
39 | * Created by Vea on 2016/11/24.
40 | * ================================================
41 | */
42 | public abstract class BaseActivity extends AppCompatActivity implements IView {
43 |
44 | @Inject
45 | protected T mPresenter;
46 |
47 | private Unbinder mUnBinder;
48 | protected View mLoadingView;
49 | private AVLoadingIndicatorView mAVLoadingIndicatorView;
50 |
51 | @Override
52 | protected void onCreate(@Nullable Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 |
55 |
56 | int layoutResID = getLayoutId();
57 | //如果initView返回0,框架则不会调用setContentView(),当然也不会 Bind ButterKnife
58 | if (layoutResID != 0) {
59 | setContentView(layoutResID);
60 | //绑定到butterknife
61 | mUnBinder = ButterKnife.bind(this);
62 | }
63 | setupActivityComponent(AtomsUtils.obtainAppComponentFromContext(this));
64 | if (mPresenter != null) {
65 | mPresenter.attachView(this);
66 | }
67 | initData(savedInstanceState);
68 | }
69 |
70 | @Override
71 | protected void onDestroy() {
72 | super.onDestroy();
73 | if (mPresenter != null) {
74 | mPresenter.detachView();
75 | mPresenter = null;
76 | }
77 | mUnBinder.unbind();
78 | }
79 |
80 | protected void setupActivityComponent(AppComponent appComponent) {
81 |
82 | }
83 |
84 | @Override
85 | public void showLoading() {
86 | if (mLoadingView == null) {
87 | if (getLoadingLayoutId() != 0 && getLoadingViewId() != 0) {
88 | initLoadingView();
89 | }
90 | }
91 |
92 | if (mLoadingView != null) {
93 | mLoadingView.bringToFront();
94 | mLoadingView.setVisibility(View.VISIBLE);
95 | mAVLoadingIndicatorView.setVisibility(View.VISIBLE);
96 | }
97 | }
98 |
99 | @Override
100 | public void hideLoading() {
101 | if (mLoadingView != null) {
102 | mLoadingView.setVisibility(View.GONE);
103 | mAVLoadingIndicatorView.setVisibility(View.GONE);
104 | }
105 | }
106 |
107 | protected int getLoadingLayoutId() {
108 | return 0;
109 | }
110 |
111 | protected int getLoadingViewId() {
112 | return 0;
113 | }
114 |
115 | private void initLoadingView() {
116 | mLoadingView = LayoutInflater.from(this).inflate(
117 | getLoadingLayoutId(), null);
118 | mAVLoadingIndicatorView = mLoadingView.findViewById(getLoadingViewId());
119 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
120 | FrameLayout.LayoutParams.MATCH_PARENT);
121 | mLoadingView.setOnTouchListener((view, motionEvent) -> true);
122 | mAVLoadingIndicatorView.show();
123 | addContentView(mLoadingView, params);
124 | }
125 |
126 | protected abstract int getLayoutId();
127 |
128 | protected abstract void initData(@Nullable Bundle savedInstanceState);
129 |
130 | @Override
131 | public void closePage() {
132 | finish();
133 | }
134 |
135 | @Override
136 | public void showMessage(String msg) {
137 | Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/base/BaseFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.base;
17 |
18 | import android.content.Context;
19 | import android.os.Bundle;
20 | import android.support.annotation.NonNull;
21 | import android.support.annotation.Nullable;
22 | import android.support.v4.app.Fragment;
23 | import android.view.LayoutInflater;
24 | import android.view.View;
25 | import android.view.ViewGroup;
26 | import android.widget.Toast;
27 |
28 | import com.vea.atoms.mvp.di.component.AppComponent;
29 | import com.vea.atoms.mvp.utils.AtomsUtils;
30 |
31 | import org.simple.eventbus.EventBus;
32 |
33 | import javax.inject.Inject;
34 |
35 | import butterknife.ButterKnife;
36 | import butterknife.Unbinder;
37 |
38 | /**
39 | * ================================================
40 | * MVP Fragment基类
41 | *
42 | * Created by Vea on 2016/11/24.
43 | * ================================================
44 | */
45 | public abstract class BaseFragment extends Fragment implements IView {
46 |
47 | @Inject
48 | protected T mPresenter;
49 |
50 | private Unbinder mUnBinder;
51 |
52 | private BaseActivity mBaseActivity;
53 |
54 | public BaseActivity getBaseActivity() {
55 | return mBaseActivity;
56 | }
57 |
58 | @Override
59 | public void onAttach(Context context) {
60 | super.onAttach(context);
61 | mBaseActivity = (BaseActivity) context;
62 | }
63 |
64 | @Nullable
65 | @Override
66 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
67 | return inflater.inflate(getLayoutId(), null);
68 | }
69 |
70 | @Override
71 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
72 | super.onViewCreated(view, savedInstanceState);
73 |
74 | setupFragmentComponent(AtomsUtils.obtainAppComponentFromContext(getActivity()));
75 | if (mPresenter != null) {
76 | mPresenter.attachView(this);
77 | }
78 | mUnBinder = ButterKnife.bind(this, view);
79 | if (useEventBus()) {
80 | EventBus.getDefault().register(this);
81 | }
82 | initData(savedInstanceState);
83 | }
84 |
85 | @Override
86 | public void onDestroyView() {
87 | if (useEventBus()) {
88 | EventBus.getDefault().unregister(this);
89 | }
90 | super.onDestroyView();
91 | mUnBinder.unbind();
92 | }
93 |
94 | @Override
95 | public void onDestroy() {
96 | super.onDestroy();
97 | if (mPresenter != null) {
98 | mPresenter.detachView();
99 | mPresenter = null;
100 | }
101 | }
102 |
103 | protected void setupFragmentComponent(AppComponent appComponent) {
104 |
105 | }
106 |
107 | protected boolean useEventBus() {
108 | return true;
109 | }
110 |
111 | protected abstract int getLayoutId();
112 |
113 | protected abstract void initData(@Nullable Bundle savedInstanceState);
114 |
115 | @Override
116 | public void showMessage(String msg) {
117 | if (getActivity() != null) {
118 | Toast.makeText(getActivity().getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
119 | }
120 | }
121 |
122 | @Override
123 | public void showLoading() {
124 | mBaseActivity.showLoading();
125 | }
126 |
127 | @Override
128 | public void hideLoading() {
129 | mBaseActivity.hideLoading();
130 | }
131 |
132 | @Override
133 | public void closePage() {
134 |
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/base/BaseLazyFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.base;
17 |
18 | import android.os.Bundle;
19 | import android.support.annotation.NonNull;
20 | import android.support.annotation.Nullable;
21 | import android.view.View;
22 |
23 | /**
24 | * ================================================
25 | * MVP 懒加载 Fragment基类
26 | *
27 | * Created by Vea on 2016/11/24.
28 | * ================================================
29 | */
30 | public abstract class BaseLazyFragment extends BaseFragment {
31 |
32 | /**
33 | * 控件是否已经初始化
34 | */
35 | private boolean isCreateView;
36 |
37 | @Override
38 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
39 | super.onViewCreated(view, savedInstanceState);
40 |
41 | isCreateView = true;
42 | if (getUserVisibleHint()) {
43 | initPrepare();
44 | }
45 | }
46 |
47 | /**
48 | * 此方法在控件初始化前调用,所以不能在此方法中直接操作控件会出现空指针
49 | *
50 | * @param isVisibleToUser
51 | */
52 | @Override
53 | public void setUserVisibleHint(boolean isVisibleToUser) {
54 | super.setUserVisibleHint(isVisibleToUser);
55 | if (isVisibleToUser) {
56 | initPrepare();
57 | }
58 | }
59 |
60 | private synchronized void initPrepare() {
61 | if (!isCreateView) {
62 | return;
63 | }
64 | onUserVisible();
65 | }
66 |
67 | /**
68 | * 当视图初始化,并且对用户可见的时候去真正的加载数据
69 | */
70 | protected abstract void onUserVisible();
71 | }
72 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/base/BasePresenter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.base;
17 |
18 | import com.vea.atoms.mvp.utils.Preconditions;
19 |
20 | import java.lang.ref.WeakReference;
21 |
22 | import io.reactivex.disposables.CompositeDisposable;
23 | import io.reactivex.disposables.Disposable;
24 |
25 | /**
26 | * ================================================
27 | * Presenter基类
28 | *
29 | * Created by Vea on 2016/11/24.
30 | * ================================================
31 | */
32 | public class BasePresenter implements IPresenter {
33 |
34 | protected WeakReference mView;
35 |
36 | CompositeDisposable mDisposables;
37 |
38 |
39 | /**
40 | * 如果当前页面不需要操作数据,只需要 View 层,则使用此构造函数
41 | *
42 | * @param rootView
43 | */
44 | public BasePresenter(T rootView) {
45 | Preconditions.checkNotNull(rootView, "%s cannot be null", IView.class.getName());
46 | this.mView = new WeakReference(rootView);
47 | }
48 |
49 | public BasePresenter() {
50 |
51 | }
52 |
53 |
54 | @Override
55 | public void attachView(T view) {
56 | if (mView == null) {
57 | mView = new WeakReference(view);
58 | }
59 | }
60 |
61 | @Override
62 | public void detachView() {
63 | mView.clear();
64 | mView = null;
65 | dispose();
66 | }
67 |
68 | public T getView() {
69 | if (mView != null) {
70 | return mView.get();
71 | }
72 | return null;
73 | }
74 |
75 | //取消所有的订阅
76 | public void dispose() {
77 | if (mDisposables != null) {
78 | mDisposables.clear();
79 | }
80 | }
81 |
82 | protected void addSubscription(Disposable disposable) {
83 | if (disposable == null) return;
84 | if (mDisposables == null) {
85 | mDisposables = new CompositeDisposable();
86 | }
87 | mDisposables.add(disposable);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/base/IPresenter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.base;
17 |
18 |
19 | /**
20 | * ================================================
21 | * 框架要求框架中的每个 Presenter 都需要实现此类,以满足规范
22 | *
23 | * @see BasePresenter
24 | * Created by Vea on 2016/11/24.
25 | * ================================================
26 | */
27 | public interface IPresenter {
28 |
29 | void attachView(T view);
30 |
31 | void detachView();
32 |
33 | }
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/base/IView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.base;
17 |
18 | /**
19 | * ================================================
20 | * 框架要求框架中的每个 View 都需要实现此类, 以满足规范
21 | *
22 | * Created by Vea on 2016/11/24.
23 | * ================================================
24 | */
25 | public interface IView {
26 |
27 | void showMessage(String msg);
28 |
29 | /**
30 | * 显示加载
31 | */
32 | void showLoading();
33 |
34 | /**
35 | * 隐藏加载
36 | */
37 | void hideLoading();
38 |
39 | /**
40 | * 关闭页面
41 | */
42 | void closePage();
43 |
44 | }
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/di/component/AppComponent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.di.component;
17 |
18 | import android.app.Application;
19 | import android.content.Context;
20 |
21 | import com.vea.atoms.mvp.app.AppDelegate;
22 | import com.vea.atoms.mvp.di.module.AppModule;
23 | import com.vea.atoms.mvp.di.module.ClientModule;
24 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
25 | import com.vea.atoms.mvp.integration.IRepositoryManager;
26 | import com.vea.atoms.mvp.integration.cache.Cache;
27 | import com.vea.atoms.mvp.utils.AtomsUtils;
28 |
29 | import javax.inject.Singleton;
30 |
31 | import dagger.BindsInstance;
32 | import dagger.Component;
33 | import okhttp3.OkHttpClient;
34 |
35 | /**
36 | * ================================================
37 | * 可通过 {@link AtomsUtils#obtainAppComponentFromContext(Context)} 拿到此接口的实现类
38 | * 拥有此接口的实现类即可调用对应的方法拿到 Dagger 提供的对应实例
39 | *
40 | * Created by Vea on 2016/11/24.
41 | * ================================================
42 | */
43 | @Singleton
44 | @Component(modules = {
45 | AppModule.class,
46 | ClientModule.class,
47 | GlobalConfigModule.class,
48 | })
49 | public interface AppComponent {
50 |
51 | Application application();
52 |
53 | //用于管理网络请求层,以及数据缓存层
54 | IRepositoryManager repositoryManager();
55 |
56 | OkHttpClient okHttpClient();
57 |
58 | //用来存取一些整个App公用的数据,切勿大量存放大容量数据
59 | Cache extras();
60 |
61 | //用于创建框架所需缓存对象的工厂
62 | Cache.Factory cacheFactory();
63 |
64 | void injectDelegate(AppDelegate delegate);
65 |
66 | @Component.Builder
67 | interface Builder {
68 | @BindsInstance
69 | Builder application(Application application);
70 |
71 | Builder globalConfigModule(GlobalConfigModule globalConfigModule);
72 |
73 | AppComponent build();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/di/module/AppModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.di.module;
17 |
18 |
19 | import com.vea.atoms.mvp.integration.IRepositoryManager;
20 | import com.vea.atoms.mvp.integration.RepositoryManager;
21 | import com.vea.atoms.mvp.integration.cache.Cache;
22 | import com.vea.atoms.mvp.integration.cache.CacheType;
23 |
24 | import javax.inject.Singleton;
25 |
26 | import dagger.Binds;
27 | import dagger.Module;
28 | import dagger.Provides;
29 |
30 | /**
31 | * ================================================
32 | * 提供一些框架必须的实例的 {@link Module}
33 | *
34 | * Created by Vea on 2016/11/24.
35 | * ================================================
36 | */
37 | @Module
38 | public abstract class AppModule {
39 |
40 | @Binds
41 | abstract IRepositoryManager bindRepositoryManager(RepositoryManager repositoryManager);
42 |
43 |
44 | @Singleton
45 | @Provides
46 | static Cache provideExtras(Cache.Factory cacheFactory) {
47 | return cacheFactory.build(CacheType.EXTRAS);
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/di/module/ClientModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.di.module;
17 |
18 | import android.app.Application;
19 | import android.content.Context;
20 | import android.support.annotation.Nullable;
21 |
22 | import com.vea.atoms.mvp.http.GlobalHttpHandler;
23 | import com.vea.atoms.mvp.http.log.RequestInterceptor;
24 |
25 | import java.io.IOException;
26 | import java.util.List;
27 | import java.util.concurrent.TimeUnit;
28 |
29 | import javax.inject.Singleton;
30 |
31 | import dagger.Binds;
32 | import dagger.Module;
33 | import dagger.Provides;
34 | import okhttp3.HttpUrl;
35 | import okhttp3.Interceptor;
36 | import okhttp3.OkHttpClient;
37 | import okhttp3.Response;
38 | import retrofit2.Retrofit;
39 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
40 | import retrofit2.converter.gson.GsonConverterFactory;
41 |
42 | /**
43 | * ================================================
44 | * 提供一些三方库客户端实例的 {@link Module}
45 | *
46 | * Created by Vea on 2018/8/24.
47 | * ================================================
48 | */
49 | @Module
50 | public abstract class ClientModule {
51 | private static final int TIME_OUT = 10;
52 |
53 | /**
54 | * 提供 {@link Retrofit}
55 | *
56 | * @param application
57 | * @param configuration
58 | * @param builder
59 | * @param client
60 | * @param httpUrl
61 | * @param gson
62 | * @return {@link Retrofit}
63 | */
64 | @Singleton
65 | @Provides
66 | static Retrofit provideRetrofit(Application application, @Nullable RetrofitConfiguration configuration, Retrofit.Builder builder, OkHttpClient client
67 | , HttpUrl httpUrl) {
68 | builder
69 | .baseUrl(httpUrl)//域名
70 | .client(client);//设置okhttp
71 |
72 | if (configuration != null)
73 | configuration.configRetrofit(application, builder);
74 |
75 | builder
76 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//使用 Rxjava
77 | .addConverterFactory(GsonConverterFactory.create());//使用 Gson
78 | return builder.build();
79 | }
80 |
81 | /**
82 | * 提供 {@link OkHttpClient}
83 | *
84 | * @param application
85 | * @param configuration
86 | * @param builder
87 | * @param intercept
88 | * @param interceptors
89 | * @param handler
90 | * @return {@link OkHttpClient}
91 | */
92 | @Singleton
93 | @Provides
94 | static OkHttpClient provideClient(Application application, @Nullable OkhttpConfiguration configuration, OkHttpClient.Builder builder, Interceptor intercept
95 | , @Nullable List interceptors, @Nullable GlobalHttpHandler handler) {
96 | builder
97 | .connectTimeout(TIME_OUT, TimeUnit.SECONDS)
98 | .readTimeout(TIME_OUT, TimeUnit.SECONDS)
99 | .addNetworkInterceptor(intercept);
100 |
101 | if (handler != null)
102 | builder.addInterceptor(new Interceptor() {
103 | @Override
104 | public Response intercept(Chain chain) throws IOException {
105 | return chain.proceed(handler.onHttpRequestBefore(chain, chain.request()));
106 | }
107 | });
108 |
109 | if (interceptors != null) {//如果外部提供了interceptor的集合则遍历添加
110 | for (Interceptor interceptor : interceptors) {
111 | builder.addInterceptor(interceptor);
112 | }
113 | }
114 |
115 | if (configuration != null)
116 | configuration.configOkhttp(application, builder);
117 | return builder.build();
118 | }
119 |
120 | @Singleton
121 | @Provides
122 | static Retrofit.Builder provideRetrofitBuilder() {
123 | return new Retrofit.Builder();
124 | }
125 |
126 | @Singleton
127 | @Provides
128 | static OkHttpClient.Builder provideClientBuilder() {
129 | return new OkHttpClient.Builder();
130 | }
131 |
132 | @Binds
133 | abstract Interceptor bindInterceptor(RequestInterceptor interceptor);
134 |
135 |
136 | public interface RetrofitConfiguration {
137 | void configRetrofit(Context context, Retrofit.Builder builder);
138 | }
139 |
140 | public interface OkhttpConfiguration {
141 | void configOkhttp(Context context, OkHttpClient.Builder builder);
142 | }
143 |
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/di/scope/ActivityScope.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.di.scope;
17 |
18 | import java.lang.annotation.Retention;
19 |
20 | import javax.inject.Scope;
21 |
22 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
23 |
24 | @Scope
25 | @Retention(RUNTIME)
26 | public @interface ActivityScope {
27 |
28 | }
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/di/scope/FragmentScope.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.di.scope;
17 |
18 | import java.lang.annotation.Retention;
19 |
20 | import javax.inject.Scope;
21 |
22 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
23 |
24 | @Scope
25 | @Retention(RUNTIME)
26 | public @interface FragmentScope {
27 | }
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/http/BaseUrl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.http;
17 |
18 | import okhttp3.HttpUrl;
19 |
20 | /**
21 | * ================================================
22 | * 针对于 BaseUrl 在 App 启动时不能确定,需要请求服务器接口动态获取的应用场景
23 | *
24 | * Created by Vea on 11/07/2017 14:58
25 | * ================================================
26 | */
27 | public interface BaseUrl {
28 | /**
29 | * 在调用 Retrofit API 接口之前,使用 Okhttp 或其他方式,请求到正确的 BaseUrl 并通过此方法返回
30 | *
31 | * @return
32 | */
33 | HttpUrl url();
34 | }
35 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/http/GlobalHttpHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.http;
17 |
18 |
19 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
20 |
21 | import okhttp3.Interceptor;
22 | import okhttp3.Request;
23 | import okhttp3.Response;
24 |
25 | /**
26 | * ================================================
27 | * 处理 Http 请求和响应结果的处理类
28 | * 使用 {@link GlobalConfigModule.Builder#globalHttpHandler(GlobalHttpHandler)} 方法配置
29 | *
30 | * Created by Vea on 8/30/16 17:47
31 | * ================================================
32 | */
33 | public interface GlobalHttpHandler {
34 | Response onHttpResultResponse(String httpResult, Interceptor.Chain chain, Response response);
35 |
36 | Request onHttpRequestBefore(Interceptor.Chain chain, Request request);
37 |
38 | //空实现
39 | GlobalHttpHandler EMPTY = new GlobalHttpHandler() {
40 | @Override
41 | public Response onHttpResultResponse(String httpResult, Interceptor.Chain chain, Response response) {
42 | //不管是否处理,都必须将response返回出去
43 | return response;
44 | }
45 |
46 | @Override
47 | public Request onHttpRequestBefore(Interceptor.Chain chain, Request request) {
48 | //不管是否处理,都必须将request返回出去
49 | return request;
50 | }
51 | };
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/http/log/FormatPrinter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.http.log;
17 |
18 |
19 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
20 |
21 | import java.util.List;
22 |
23 | import okhttp3.MediaType;
24 | import okhttp3.Request;
25 |
26 | /**
27 | * ================================================
28 | * 对 OkHttp 的请求和响应信息进行更规范和清晰的打印, 开发者可更根据自己的需求自行扩展打印格式
29 | *
30 | * @see DefaultFormatPrinter
31 | * @see GlobalConfigModule.Builder#formatPrinter(FormatPrinter)
32 | * Created by Vea on 31/01/2018 17:36
33 | * ================================================
34 | */
35 |
36 | public interface FormatPrinter {
37 |
38 | /**
39 | * 打印网络请求信息, 当网络请求时 {{@link okhttp3.RequestBody}} 可以解析的情况
40 | *
41 | * @param request
42 | * @param bodyString 发送给服务器的请求体中的数据(已解析)
43 | */
44 | void printJsonRequest(Request request, String bodyString);
45 |
46 | /**
47 | * 打印网络请求信息, 当网络请求时 {{@link okhttp3.RequestBody}} 为 {@code null} 或不可解析的情况
48 | *
49 | * @param request
50 | */
51 | void printFileRequest(Request request);
52 |
53 | /**
54 | * 打印网络响应信息, 当网络响应时 {{@link okhttp3.ResponseBody}} 可以解析的情况
55 | *
56 | * @param chainMs 服务器响应耗时(单位毫秒)
57 | * @param isSuccessful 请求是否成功
58 | * @param code 响应码
59 | * @param headers 请求头
60 | * @param contentType 服务器返回数据的数据类型
61 | * @param bodyString 服务器返回的数据(已解析)
62 | * @param segments 域名后面的资源地址
63 | * @param message 响应信息
64 | * @param responseUrl 请求地址
65 | */
66 | void printJsonResponse(long chainMs, boolean isSuccessful, int code, String headers, MediaType contentType,
67 | String bodyString, List segments, String message, String responseUrl);
68 |
69 | /**
70 | * 打印网络响应信息, 当网络响应时 {{@link okhttp3.ResponseBody}} 为 {@code null} 或不可解析的情况
71 | *
72 | * @param chainMs 服务器响应耗时(单位毫秒)
73 | * @param isSuccessful 请求是否成功
74 | * @param code 响应码
75 | * @param headers 请求头
76 | * @param segments 域名后面的资源地址
77 | * @param message 响应信息
78 | * @param responseUrl 请求地址
79 | */
80 | void printFileResponse(long chainMs, boolean isSuccessful, int code, String headers,
81 | List segments, String message, String responseUrl);
82 | }
83 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/integration/ConfigModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.integration;
17 |
18 | import android.content.Context;
19 |
20 | import com.vea.atoms.mvp.app.AppLifecycles;
21 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * ================================================
27 | * {@link ConfigModule} 可以给框架配置一些参数,需要实现 {@link ConfigModule} 后,在 AndroidManifest 中声明该实现类
28 | *
29 | * Created by Vea on 12/04/2017 11:37
30 | * ================================================
31 | */
32 | public interface ConfigModule {
33 |
34 | /**
35 | * 使用{@link GlobalConfigModule.Builder}给框架配置一些配置参数
36 | *
37 | * @param context
38 | * @param builder
39 | */
40 | void applyOptions(Context context, GlobalConfigModule.Builder builder);
41 |
42 | /**
43 | * 使用{@link AppLifecycles}在Application的生命周期中注入一些操作
44 | *
45 | * @param context
46 | * @param lifecycles
47 | */
48 | void injectAppLifecycle(Context context, List lifecycles);
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/integration/IRepositoryManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.integration;
17 |
18 |
19 | /**
20 | * ================================================
21 | * 用来管理网络请求层
22 | *
23 | * Created by Vea on 17/03/2017 11:15
24 | * ================================================
25 | */
26 | public interface IRepositoryManager {
27 |
28 | /**
29 | * 根据传入的 Class 获取对应的 Retrofit service
30 | *
31 | * @param service
32 | * @param
33 | * @return
34 | */
35 | T obtainRetrofitService(Class service);
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/integration/ManifestParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.integration;
17 |
18 | import android.content.Context;
19 | import android.content.pm.ApplicationInfo;
20 | import android.content.pm.PackageManager;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | /**
26 | * ================================================
27 | * 用于解析 AndroidManifest 中的 Meta 属性
28 | * 配合 {@link ConfigModule} 使用
29 | *
30 | * Created by Vea on 12/04/2017 14:41
31 | * ================================================
32 | */
33 | public final class ManifestParser {
34 | private static final String MODULE_VALUE = "ConfigModule";
35 |
36 | private final Context context;
37 |
38 | public ManifestParser(Context context) {
39 | this.context = context;
40 | }
41 |
42 | public List parse() {
43 | List modules = new ArrayList();
44 | try {
45 | ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
46 | context.getPackageName(), PackageManager.GET_META_DATA);
47 | if (appInfo.metaData != null) {
48 | for (String key : appInfo.metaData.keySet()) {
49 | if (MODULE_VALUE.equals(appInfo.metaData.get(key))) {
50 |
51 | try {
52 | Class> clazz = Class.forName(key);
53 | modules.add(parseModule(key));
54 | } catch (ClassNotFoundException e) {
55 | }
56 | }
57 | }
58 | }
59 | } catch (PackageManager.NameNotFoundException e) {
60 | throw new RuntimeException("Unable to find metadata to parse ConfigModule", e);
61 | }
62 |
63 | return modules;
64 | }
65 |
66 | private static ConfigModule parseModule(String className) {
67 | Class> clazz;
68 | try {
69 | clazz = Class.forName(className);
70 | } catch (ClassNotFoundException e) {
71 | throw new IllegalArgumentException("Unable to find ConfigModule implementation", e);
72 | }
73 |
74 | Object module;
75 | try {
76 | module = clazz.newInstance();
77 | } catch (InstantiationException e) {
78 | throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e);
79 | } catch (IllegalAccessException e) {
80 | throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e);
81 | }
82 |
83 | if (!(module instanceof ConfigModule)) {
84 | throw new RuntimeException("Expected instanceof ConfigModule, but found: " + module);
85 | }
86 | return (ConfigModule) module;
87 | }
88 | }
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/integration/RepositoryManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.integration;
17 |
18 |
19 | import com.vea.atoms.mvp.integration.cache.Cache;
20 | import com.vea.atoms.mvp.integration.cache.CacheType;
21 | import com.vea.atoms.mvp.utils.Preconditions;
22 |
23 | import javax.inject.Inject;
24 | import javax.inject.Singleton;
25 |
26 | import dagger.Lazy;
27 | import retrofit2.Retrofit;
28 |
29 | /**
30 | * ================================================
31 | * IRepositoryManager实现类用来管理网络请求层
32 | *
33 | * Created by Vea on 13/04/2017 09:52
34 | * ================================================
35 | */
36 | @Singleton
37 | public class RepositoryManager implements IRepositoryManager {
38 | @Inject
39 | Lazy mRetrofit;
40 |
41 | @Inject
42 | Cache.Factory mCachefactory;
43 |
44 | private Cache mRetrofitServiceCache;
45 |
46 | @Inject
47 | public RepositoryManager() {
48 | }
49 |
50 | /**
51 | * 根据传入的 Class 获取对应的 Retrofit service
52 | *
53 | * @param service
54 | * @param
55 | * @return
56 | */
57 | @Override
58 | public synchronized T obtainRetrofitService(Class service) {
59 | if (mRetrofitServiceCache == null)
60 | mRetrofitServiceCache = mCachefactory.build(CacheType.RETROFIT_SERVICE_CACHE);
61 | Preconditions.checkNotNull(mRetrofitServiceCache, "Cannot return null from a Cache.Factory#build(int) method");
62 | T retrofitService = (T) mRetrofitServiceCache.get(service.getCanonicalName());
63 | if (retrofitService == null) {
64 | retrofitService = mRetrofit.get().create(service);
65 | mRetrofitServiceCache.put(service.getCanonicalName(), retrofitService);
66 | }
67 | return retrofitService;
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/integration/cache/Cache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.integration.cache;
17 |
18 | import android.app.Application;
19 | import android.support.annotation.NonNull;
20 | import android.support.annotation.Nullable;
21 |
22 | import com.vea.atoms.mvp.di.module.GlobalConfigModule;
23 |
24 | import java.util.Set;
25 |
26 | /**
27 | * ================================================
28 | * 用于缓存框架中所必需的组件,开发者可通过 {@link GlobalConfigModule.Builder#cacheFactory(Factory)} 为框架提供缓存策略
29 | * 开发者也可以用于自己日常中的使用
30 | *
31 | * @see GlobalConfigModule#provideCacheFactory(Application)
32 | * @see LruCache
33 | * Created by Vea on 25/09/2017 16:36
34 | * ================================================
35 | */
36 | public interface Cache {
37 | interface Factory {
38 |
39 | /**
40 | * Returns a new cache
41 | *
42 | * @param type 框架中需要缓存的模块类型
43 | * @return {@link Cache}
44 | */
45 | @NonNull
46 | Cache build(CacheType type);
47 | }
48 |
49 | /**
50 | * 返回当前缓存已占用的总 size
51 | *
52 | * @return {@code size}
53 | */
54 | int size();
55 |
56 | /**
57 | * 返回当前缓存所能允许的最大 size
58 | *
59 | * @return {@code maxSize}
60 | */
61 | int getMaxSize();
62 |
63 | /**
64 | * 返回这个 {@code key} 在缓存中对应的 {@code value}, 如果返回 {@code null} 说明这个 {@code key} 没有对应的 {@code value}
65 | *
66 | * @param key {@code key}
67 | * @return {@code value}
68 | */
69 | @Nullable
70 | V get(K key);
71 |
72 | /**
73 | * 将 {@code key} 和 {@code value} 以条目的形式加入缓存,如果这个 {@code key} 在缓存中已经有对应的 {@code value}
74 | * 则此 {@code value} 被新的 {@code value} 替换并返回,如果为 {@code null} 说明是一个新条目
75 | *
76 | * @param key {@code key}
77 | * @param value {@code value}
78 | * @return 如果这个 {@code key} 在容器中已经储存有 {@code value}, 则返回之前的 {@code value} 否则返回 {@code null}
79 | */
80 | @Nullable
81 | V put(K key, V value);
82 |
83 | /**
84 | * 移除缓存中这个 {@code key} 所对应的条目,并返回所移除条目的 value
85 | * 如果返回为 {@code null} 则有可能时因为这个 {@code key} 对应的 value 为 {@code null} 或条目不存在
86 | *
87 | * @param key {@code key}
88 | * @return 如果这个 {@code key} 在容器中已经储存有 {@code value} 并且删除成功则返回删除的 {@code value}, 否则返回 {@code null}
89 | */
90 | @Nullable
91 | V remove(K key);
92 |
93 | /**
94 | * 如果这个 {@code key} 在缓存中有对应的 value 并且不为 {@code null}, 则返回 {@code true}
95 | *
96 | * @param key {@code key}
97 | * @return {@code true} 为在容器中含有这个 {@code key}, 否则为 {@code false}
98 | */
99 | boolean containsKey(K key);
100 |
101 | /**
102 | * 返回当前缓存中含有的所有 {@code key}
103 | *
104 | * @return {@code keySet}
105 | */
106 | Set keySet();
107 |
108 | /**
109 | * 清除缓存中所有的内容
110 | */
111 | void clear();
112 | }
113 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/integration/cache/CacheType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.integration.cache;
17 |
18 | import android.app.Activity;
19 | import android.app.ActivityManager;
20 | import android.content.Context;
21 | import android.support.v4.app.Fragment;
22 |
23 | import com.vea.atoms.mvp.di.component.AppComponent;
24 | import com.vea.atoms.mvp.integration.RepositoryManager;
25 |
26 | /**
27 | * ================================================
28 | * 构建 {@link Cache} 时,使用 {@link CacheType} 中声明的类型,来区分不同的模块
29 | * 从而为不同的模块构建不同的缓存策略
30 | *
31 | * @see Cache.Factory#build(CacheType)
32 | * Created by Vea on 25/09/2017 18:05
33 | * ================================================
34 | */
35 | public interface CacheType {
36 | int RETROFIT_SERVICE_CACHE_TYPE_ID = 0;
37 | int CACHE_SERVICE_CACHE_TYPE_ID = 1;
38 | int EXTRAS_TYPE_ID = 2;
39 | int ACTIVITY_CACHE_TYPE_ID = 3;
40 | int FRAGMENT_CACHE_TYPE_ID = 4;
41 | /**
42 | * {@link RepositoryManager}中存储 Retrofit Service 的容器
43 | */
44 | CacheType RETROFIT_SERVICE_CACHE = new CacheType() {
45 | private static final int MAX_SIZE = 150;
46 | private static final float MAX_SIZE_MULTIPLIER = 0.002f;
47 |
48 | @Override
49 | public int getCacheTypeId() {
50 | return RETROFIT_SERVICE_CACHE_TYPE_ID;
51 | }
52 |
53 | @Override
54 | public int calculateCacheSize(Context context) {
55 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
56 | int targetMemoryCacheSize = (int) (activityManager.getMemoryClass() * MAX_SIZE_MULTIPLIER * 1024);
57 | if (targetMemoryCacheSize >= MAX_SIZE) {
58 | return MAX_SIZE;
59 | }
60 | return targetMemoryCacheSize;
61 | }
62 | };
63 |
64 | /**
65 | * {@link RepositoryManager} 中储存 Cache Service 的容器
66 | */
67 | CacheType CACHE_SERVICE_CACHE = new CacheType() {
68 | private static final int MAX_SIZE = 150;
69 | private static final float MAX_SIZE_MULTIPLIER = 0.002f;
70 |
71 | @Override
72 | public int getCacheTypeId() {
73 | return CACHE_SERVICE_CACHE_TYPE_ID;
74 | }
75 |
76 | @Override
77 | public int calculateCacheSize(Context context) {
78 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
79 | int targetMemoryCacheSize = (int) (activityManager.getMemoryClass() * MAX_SIZE_MULTIPLIER * 1024);
80 | if (targetMemoryCacheSize >= MAX_SIZE) {
81 | return MAX_SIZE;
82 | }
83 | return targetMemoryCacheSize;
84 | }
85 | };
86 |
87 | /**
88 | * {@link AppComponent} 中的 extras
89 | */
90 | CacheType EXTRAS = new CacheType() {
91 | private static final int MAX_SIZE = 500;
92 | private static final float MAX_SIZE_MULTIPLIER = 0.005f;
93 |
94 | @Override
95 | public int getCacheTypeId() {
96 | return EXTRAS_TYPE_ID;
97 | }
98 |
99 | @Override
100 | public int calculateCacheSize(Context context) {
101 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
102 | int targetMemoryCacheSize = (int) (activityManager.getMemoryClass() * MAX_SIZE_MULTIPLIER * 1024);
103 | if (targetMemoryCacheSize >= MAX_SIZE) {
104 | return MAX_SIZE;
105 | }
106 | return targetMemoryCacheSize;
107 | }
108 | };
109 |
110 | /**
111 | * {@link Activity} 中存储数据的容器
112 | */
113 | CacheType ACTIVITY_CACHE = new CacheType() {
114 | private static final int MAX_SIZE = 80;
115 | private static final float MAX_SIZE_MULTIPLIER = 0.0008f;
116 |
117 | @Override
118 | public int getCacheTypeId() {
119 | return ACTIVITY_CACHE_TYPE_ID;
120 | }
121 |
122 | @Override
123 | public int calculateCacheSize(Context context) {
124 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
125 | int targetMemoryCacheSize = (int) (activityManager.getMemoryClass() * MAX_SIZE_MULTIPLIER * 1024);
126 | if (targetMemoryCacheSize >= MAX_SIZE) {
127 | return MAX_SIZE;
128 | }
129 | return targetMemoryCacheSize;
130 | }
131 | };
132 |
133 | /**
134 | * {@link Fragment} 中存储数据的容器
135 | */
136 | CacheType FRAGMENT_CACHE = new CacheType() {
137 | private static final int MAX_SIZE = 80;
138 | private static final float MAX_SIZE_MULTIPLIER = 0.0008f;
139 |
140 | @Override
141 | public int getCacheTypeId() {
142 | return FRAGMENT_CACHE_TYPE_ID;
143 | }
144 |
145 | @Override
146 | public int calculateCacheSize(Context context) {
147 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
148 | int targetMemoryCacheSize = (int) (activityManager.getMemoryClass() * MAX_SIZE_MULTIPLIER * 1024);
149 | if (targetMemoryCacheSize >= MAX_SIZE) {
150 | return MAX_SIZE;
151 | }
152 | return targetMemoryCacheSize;
153 | }
154 | };
155 |
156 | /**
157 | * 返回框架内需要缓存的模块对应的 {@code id}
158 | *
159 | * @return
160 | */
161 | int getCacheTypeId();
162 |
163 | /**
164 | * 计算对应模块需要的缓存大小
165 | *
166 | * @return
167 | */
168 | int calculateCacheSize(Context context);
169 | }
170 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/integration/cache/IntelligentCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.integration.cache;
17 |
18 | import android.support.annotation.Nullable;
19 |
20 | import java.util.HashMap;
21 | import java.util.Map;
22 | import java.util.Set;
23 |
24 | /**
25 | * ================================================
26 | * {@link IntelligentCache} 含有可将数据永久存储至内存中的存储容器 {@link #mMap}, 和当达到最大容量时可根据 LRU
27 | * 算法抛弃不合规数据的存储容器 {@link #mCache}
28 | *
29 | * {@link IntelligentCache} 可根据您传入的 {@code key} 智能的判断您需要将数据存储至哪个存储容器, 从而针对数据
30 | * 的不同特性进行不同的存储优化
31 | *
32 | * 调用 {@link IntelligentCache#put(Object, Object)} 方法, 使用 {@link #KEY_KEEP} + {@code key} 作为 key 传入的
33 | * {@code value} 可存储至 {@link #mMap} (数据永久存储至内存中, 适合比较重要的数据) 中, 否则储存至 {@link #mCache}
34 | *
35 | * Created by Vea on 12/04/2018 16:06
36 | * ================================================
37 | */
38 | public class IntelligentCache implements Cache {
39 | private final Map mMap;//可将数据永久存储至内存中的存储容器
40 | private final Cache mCache;//当达到最大容量时可根据 LRU 算法抛弃不合规数据的存储容器
41 | public static final String KEY_KEEP = "Keep=";
42 |
43 | public IntelligentCache(int size) {
44 | this.mMap = new HashMap<>();
45 | this.mCache = new LruCache<>(size);
46 | }
47 |
48 | /**
49 | * 将 {@link #mMap} 和 {@link #mCache} 的 {@code size} 相加后返回
50 | *
51 | * @return 相加后的 {@code size}
52 | */
53 | @Override
54 | public synchronized int size() {
55 | return mMap.size() + mCache.size();
56 | }
57 |
58 | /**
59 | * 将 {@link #mMap} 和 {@link #mCache} 的 {@code maxSize} 相加后返回
60 | *
61 | * @return 相加后的 {@code maxSize}
62 | */
63 | @Override
64 | public synchronized int getMaxSize() {
65 | return mMap.size() + mCache.getMaxSize();
66 | }
67 |
68 | /**
69 | * 如果在 {@code key} 中使用 {@link #KEY_KEEP} 作为其前缀, 则操作 {@link #mMap}, 否则操作 {@link #mCache}
70 | *
71 | * @param key {@code key}
72 | * @return {@code value}
73 | */
74 | @Nullable
75 | @Override
76 | public synchronized V get(String key) {
77 | if (key.startsWith(KEY_KEEP)) {
78 | return mMap.get(key);
79 | }
80 | return mCache.get(key);
81 | }
82 |
83 | /**
84 | * 如果在 {@code key} 中使用 {@link #KEY_KEEP} 作为其前缀, 则操作 {@link #mMap}, 否则操作 {@link #mCache}
85 | *
86 | * @param key {@code key}
87 | * @param value {@code value}
88 | * @return 如果这个 {@code key} 在容器中已经储存有 {@code value}, 则返回之前的 {@code value} 否则返回 {@code null}
89 | */
90 | @Nullable
91 | @Override
92 | public synchronized V put(String key, V value) {
93 | if (key.startsWith(KEY_KEEP)) {
94 | return mMap.put(key, value);
95 | }
96 | return mCache.put(key, value);
97 | }
98 |
99 | /**
100 | * 如果在 {@code key} 中使用 {@link #KEY_KEEP} 作为其前缀, 则操作 {@link #mMap}, 否则操作 {@link #mCache}
101 | *
102 | * @param key {@code key}
103 | * @return 如果这个 {@code key} 在容器中已经储存有 {@code value} 并且删除成功则返回删除的 {@code value}, 否则返回 {@code null}
104 | */
105 | @Nullable
106 | @Override
107 | public synchronized V remove(String key) {
108 | if (key.startsWith(KEY_KEEP)) {
109 | return mMap.remove(key);
110 | }
111 | return mCache.remove(key);
112 | }
113 |
114 | /**
115 | * 如果在 {@code key} 中使用 {@link #KEY_KEEP} 作为其前缀, 则操作 {@link #mMap}, 否则操作 {@link #mCache}
116 | *
117 | * @param key {@code key}
118 | * @return {@code true} 为在容器中含有这个 {@code key}, 否则为 {@code false}
119 | */
120 | @Override
121 | public synchronized boolean containsKey(String key) {
122 | if (key.startsWith(KEY_KEEP)) {
123 | return mMap.containsKey(key);
124 | }
125 | return mCache.containsKey(key);
126 | }
127 |
128 | /**
129 | * 将 {@link #mMap} 和 {@link #mCache} 的 {@code keySet} 合并返回
130 | *
131 | * @return 合并后的 {@code keySet}
132 | */
133 | @Override
134 | public synchronized Set keySet() {
135 | Set set = mCache.keySet();
136 | set.addAll(mMap.keySet());
137 | return set;
138 | }
139 |
140 | /**
141 | * 清空 {@link #mMap} 和 {@link #mCache} 容器
142 | */
143 | @Override
144 | public void clear() {
145 | mCache.clear();
146 | mMap.clear();
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/utils/CharacterHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vea
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.utils;
17 |
18 | import android.text.InputFilter;
19 | import android.text.Spanned;
20 | import android.text.TextUtils;
21 |
22 | import org.json.JSONArray;
23 | import org.json.JSONException;
24 | import org.json.JSONObject;
25 |
26 | import java.io.StringReader;
27 | import java.io.StringWriter;
28 | import java.util.regex.Matcher;
29 | import java.util.regex.Pattern;
30 |
31 | import javax.xml.transform.OutputKeys;
32 | import javax.xml.transform.Source;
33 | import javax.xml.transform.Transformer;
34 | import javax.xml.transform.TransformerException;
35 | import javax.xml.transform.TransformerFactory;
36 | import javax.xml.transform.stream.StreamResult;
37 | import javax.xml.transform.stream.StreamSource;
38 |
39 | /**
40 | * ================================================
41 | * 处理字符串的工具类
42 | *
43 | * Created by Vea on 2016/3/16
44 | * ================================================
45 | */
46 | public class CharacterHandler {
47 |
48 | private CharacterHandler() {
49 | throw new IllegalStateException("you can't instantiate me!");
50 | }
51 |
52 | public static final InputFilter emojiFilter = new InputFilter() {//emoji过滤器
53 |
54 | Pattern emoji = Pattern.compile(
55 | "[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
56 | Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
57 |
58 | @Override
59 | public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
60 | int dend) {
61 |
62 | Matcher emojiMatcher = emoji.matcher(source);
63 | if (emojiMatcher.find()) {
64 | return "";
65 | }
66 |
67 | return null;
68 | }
69 | };
70 |
71 |
72 | /**
73 | * 字符串转换成十六进制字符串
74 | *
75 | * @return String 每个Byte之间空格分隔,如: [61 6C 6B]
76 | */
77 | public static String str2HexStr(String str) {
78 |
79 | char[] chars = "0123456789ABCDEF".toCharArray();
80 | StringBuilder sb = new StringBuilder("");
81 | byte[] bs = str.getBytes();
82 | int bit;
83 |
84 | for (int i = 0; i < bs.length; i++) {
85 | bit = (bs[i] & 0x0f0) >> 4;
86 | sb.append(chars[bit]);
87 | bit = bs[i] & 0x0f;
88 | sb.append(chars[bit]);
89 | }
90 | return sb.toString().trim();
91 | }
92 |
93 |
94 | /**
95 | * json 格式化
96 | *
97 | * @param json
98 | * @return
99 | */
100 | public static String jsonFormat(String json) {
101 | if (TextUtils.isEmpty(json)) {
102 | return "Empty/Null json content";
103 | }
104 | String message;
105 | try {
106 | json = json.trim();
107 | if (json.startsWith("{")) {
108 | JSONObject jsonObject = new JSONObject(json);
109 | message = jsonObject.toString(4);
110 | } else if (json.startsWith("[")) {
111 | JSONArray jsonArray = new JSONArray(json);
112 | message = jsonArray.toString(4);
113 | } else {
114 | message = json;
115 | }
116 | } catch (JSONException e) {
117 | message = json;
118 | }
119 | return message;
120 | }
121 |
122 |
123 | /**
124 | * xml 格式化
125 | *
126 | * @param xml
127 | * @return
128 | */
129 | public static String xmlFormat(String xml) {
130 | if (TextUtils.isEmpty(xml)) {
131 | return "Empty/Null xml content";
132 | }
133 | String message;
134 | try {
135 | Source xmlInput = new StreamSource(new StringReader(xml));
136 | StreamResult xmlOutput = new StreamResult(new StringWriter());
137 | Transformer transformer = TransformerFactory.newInstance().newTransformer();
138 | transformer.setOutputProperty(OutputKeys.INDENT, "yes");
139 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
140 | transformer.transform(xmlInput, xmlOutput);
141 | message = xmlOutput.getWriter().toString().replaceFirst(">", ">\n");
142 | } catch (TransformerException e) {
143 | message = xml;
144 | }
145 | return message;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/atoms/src/main/java/com/vea/atoms/mvp/utils/UrlEncoderUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 JessYan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.vea.atoms.mvp.utils;
17 |
18 | /**
19 | * ================================================
20 | * Created by JessYan on 2018/9/14 14:10
21 | * Contact me
22 | * Follow me
23 | * ================================================
24 | */
25 | public class UrlEncoderUtils {
26 |
27 | private UrlEncoderUtils() {
28 | throw new IllegalStateException("you can't instantiate me!");
29 | }
30 |
31 | /**
32 | * 判断 str 是否已经 URLEncoder.encode() 过
33 | * 经常遇到这样的情况, 拿到一个 URL, 但是搞不清楚到底要不要 URLEncoder.encode()
34 | * 不做 URLEncoder.encode() 吧, 担心出错, 做 URLEncoder.encode() 吧, 又怕重复了
35 | *
36 | * @param str 需要判断的内容
37 | * @return 返回 {@code true} 为被 URLEncoder.encode() 过
38 | */
39 | public static boolean hasUrlEncoded(String str) {
40 | boolean encode = false;
41 | for (int i = 0; i < str.length(); i++) {
42 | char c = str.charAt(i);
43 | if (c == '%' && (i + 2) < str.length()) {
44 | // 判断是否符合urlEncode规范
45 | char c1 = str.charAt(i + 1);
46 | char c2 = str.charAt(i + 2);
47 | if (isValidHexChar(c1) && isValidHexChar(c2)) {
48 | encode = true;
49 | break;
50 | } else {
51 | break;
52 | }
53 | }
54 | }
55 | return encode;
56 | }
57 |
58 | /**
59 | * 判断 c 是否是 16 进制的字符
60 | *
61 | * @param c 需要判断的字符
62 | * @return 返回 {@code true} 为 16 进制的字符
63 | */
64 | private static boolean isValidHexChar(char c) {
65 | return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/atoms/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | atoms
3 |
4 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | apply from: "config.gradle"
3 |
4 | buildscript {
5 | ext.kotlin_version = '1.3.11'
6 | repositories {
7 | google()
8 | jcenter()
9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.2.1'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-SNAPSHOT'
15 | //如果 ButterKnife 插件和其他插件发生冲突而报错请试试 v8.4.0 版本的 ButterKnife 插件, 注意 v8.4.0 最高只能支持 com.android.tools.build:gradle:3.0.1
16 | // classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'
17 | // NOTE: Do not place your application dependencies here; they belong
18 | // in the individual module build.gradle files
19 | classpath 'com.alibaba:arouter-register:1.0.2'
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | google()
26 | jcenter()
27 | maven { url "https://jitpack.io" }
28 | }
29 |
30 | subprojects {
31 | project.configurations.all {
32 | resolutionStrategy.eachDependency { details ->
33 | if (details.requested.group == 'com.android.support'
34 | && !details.requested.name.contains('multidex')) {
35 | details.useVersion rootProject.ext.version["androidSupportSdkVersion"]
36 | }
37 | }
38 | }
39 |
40 | }
41 | }
42 |
43 | task clean(type: Delete) {
44 | delete rootProject.buildDir
45 | }
46 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/gradle.properties
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 07 13:54:39 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/image/atoms_banner_v1.0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/image/atoms_banner_v1.0.jpg
--------------------------------------------------------------------------------
/qrcode_for_gh_e708d5b47c85_258.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XWC95/Atoms-mvp/5a4f0626eab0c9789a579139f18f908d59885a1f/qrcode_for_gh_e708d5b47c85_258.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':atoms', ':CommonSDK', ':Module-gank', ':CommonService'
2 |
--------------------------------------------------------------------------------