├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── wuxiaolong │ │ └── modularsample │ │ ├── AndroidApplication.java │ │ └── MainActivity.java │ └── res │ └── layout │ └── app_activity_main.xml ├── build.gradle ├── common ├── .gitignore ├── aars │ └── AndroidUtils1.0.7.aar ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── wuxiaolong │ │ └── common │ │ ├── activity │ │ ├── BaseActivity.java │ │ └── ButterKnifeActivity.java │ │ ├── model │ │ ├── UserModel.java │ │ └── WeatherModel.java │ │ └── retrofit │ │ ├── ApiCallback.java │ │ ├── ApiClient.java │ │ └── ApiStores.java │ └── res │ └── layout │ └── toolbar.xml ├── config.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── module1 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── wuxiaolong │ │ └── module1 │ │ ├── MainActivity.java │ │ ├── Module1Fragment.java │ │ ├── Module1ServiceImpl.java │ │ └── debug │ │ └── Module1Application.java │ ├── release │ └── AndroidManifest.xml │ └── res │ └── layout │ ├── module1_activity_main.xml │ └── module1_fragment_module1.xml ├── module2 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── wuxiaolong │ │ └── module2 │ │ └── MainActivity.java │ ├── release │ └── AndroidManifest.xml │ └── res │ └── layout │ └── module2_activity_main.xml ├── resource ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── res │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── router ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── wuxiaolong │ │ └── router │ │ ├── Module1Service.java │ │ ├── RouterConstants.java │ │ └── RouterUtils.java │ └── res │ └── values │ └── strings.xml ├── settings.gradle └── versions.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 效果预览 3 | ![](http://7q5c2h.com1.z0.glb.clouddn.com/ModularSample.gif?watermark/2/text/5ZC05bCP6b6Z5ZCM5a24/font/5qW35L2T/fontsize/500/fill/I0VGRUZFRg==/dissolve/100/gravity/SouthEast/dx/10/dy/10) 4 | 5 | # 详情介绍 6 | [Android 组件化探索与思考](http://wuxiaolong.me/2017/08/01/ModularExploree/),来自我的博客,推荐 7 | 8 | [Android 组件化探索与思考](http://mp.weixin.qq.com/s/RGmzjIM4y7Yxz723Vp8uzA),来自我的公众号 9 | 10 | 11 | # 微信公众号 12 | ![](http://7q5c2h.com1.z0.glb.clouddn.com/qrcode_WuXiaolong1.JPG) 13 | 14 | # 赞赏作者 15 | ![](http://7q5c2h.com1.z0.glb.clouddn.com/wechatpay.JPG) 16 | 17 | # 更新记录 18 | * v0.03 19 | 1. 统一管理了build.gradle文件 20 | 2. 现在只要是'module'开头的module,都可以使用同一份build.gradle,配置参见'rootDir/config.gradle' 21 | 22 | * v0.02 23 | 24 | 1. 新增 resource,存放项目的所有资源,从 common 分出来 25 | 26 | 2. 新增 router,路由,所有页面请求都由它中转 27 | 28 | * v0.01 29 | 30 | 1. 组件化初步形成 31 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply from: config 2 | 3 | dependencies { 4 | compile fileTree(include: ['*.jar'], dir: 'libs') 5 | 6 | //arouter 7 | annotationProcessor arouterCompiler 8 | 9 | //butterknife 10 | annotationProcessor butterknifeCompiler 11 | 12 | //dagger2 13 | annotationProcessor dagger2Compiler 14 | 15 | if (isDebug.toBoolean()) { 16 | //当isDebug true,app得依赖基础库,保证app不报错 17 | compile project(':resource') 18 | } else { 19 | compile project(':module1') 20 | compile project(':module2') 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/wuxiaolong/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/wuxiaolong/modularsample/AndroidApplication.java: -------------------------------------------------------------------------------- 1 | package com.wuxiaolong.modularsample; 2 | 3 | import android.app.Application; 4 | 5 | import com.alibaba.android.arouter.launcher.ARouter; 6 | 7 | /** 8 | * Created by WuXiaolong on 2017/7/24. 9 | * 个人博客:http://wuxiaolong.me 10 | */ 11 | public class AndroidApplication extends Application { 12 | @Override 13 | public void onCreate() { 14 | super.onCreate(); 15 | if (BuildConfig.DEBUG) { 16 | // 这两行必须写在init之前,否则这些配置在init过程中将无效 17 | ARouter.openLog(); // 打印日志 18 | ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险) 19 | ARouter.printStackTrace(); // 打印日志的时候打印线程堆栈 20 | } 21 | ARouter.init(this); // 尽可能早,推荐在Application中初始化 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/wuxiaolong/modularsample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.wuxiaolong.modularsample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.View; 6 | 7 | import com.alibaba.android.arouter.launcher.ARouter; 8 | import com.wuxiaolong.common.activity.BaseActivity; 9 | import com.wuxiaolong.common.model.UserModel; 10 | import com.wuxiaolong.router.Module1Service; 11 | import com.wuxiaolong.router.RouterConstants; 12 | import com.wuxiaolong.router.RouterUtils; 13 | 14 | import butterknife.OnClick; 15 | 16 | /** 17 | * Created by WuXiaolong on 2017/7/24. 18 | * 个人博客:http://wuxiaolong.me 19 | */ 20 | public class MainActivity extends BaseActivity { 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.app_activity_main); 26 | initToolBarAsHome(getString(R.string.app)); 27 | } 28 | 29 | @OnClick({R.id.button1, R.id.button2, R.id.button3, R.id.button4}) 30 | public void onViewClicked(View view) { 31 | switch (view.getId()) { 32 | case R.id.button1: 33 | RouterUtils.navigation(RouterConstants.MODULE1_MAIN_ACTIVITY); 34 | break; 35 | case R.id.button2: 36 | UserModel userModel = new UserModel(); 37 | userModel.setName("WuXiaolong"); 38 | userModel.setMessage("个人博客:http://wuxiaolong.me"); 39 | Bundle bundle = new Bundle(); 40 | bundle.putSerializable("obj", userModel); 41 | ARouter.getInstance() 42 | .build(RouterConstants.MODULE1_MAIN_ACTIVITY) 43 | .with(bundle) 44 | .navigation(); 45 | break; 46 | case R.id.button3: 47 | showFragment(); 48 | break; 49 | case R.id.button4: 50 | Module1Service module1Service = (Module1Service) RouterUtils.navigation(RouterConstants.MODULE1_SERVICE_IMPL); 51 | if (module1Service != null) 52 | toastShow("结果:" + module1Service.share()); 53 | break; 54 | } 55 | } 56 | 57 | private void showFragment() { 58 | // 获取Fragment 59 | Fragment fragment = (Fragment) RouterUtils.navigation(RouterConstants.MODULE1_MODULE1_FRAGMENT); 60 | if (fragment != null) 61 | getSupportFragmentManager().beginTransaction().add(R.id.contentLayout, fragment).commit(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/res/layout/app_activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 |