ARouter是阿里在github上面的一個開源項目,地址是:ARouter 本文不是重點分享ARouter的使用,而是分享使用ARouter如何去組件化。關於它的詳細使用,你們能夠看文檔以及加羣向詢問。關於如何編寫一個路由實現組件化,推薦看我同事的一篇文章手把手教你寫Router框架入門篇java
項目結構是: android
咱們是須要拆分組件,不一樣的模塊負責本身的業務實現,不和其餘模塊有依賴關係的存在。假如這個模塊須要啓動別的Activity或者是調用別的模塊方法,咱們就經過ARouter提供的方法去實現。模塊圖以下: git
咱們使用一個ModuleManager,提供一個Map,Map是使用對應module的Provider的path做爲key和value。以及相關的數據結構,用來對ARouter的進行二次封裝和管理模塊。 大概實現以下:github
public class ModuleManager {
private ModuleOptions options;
private ModuleManager() {
}
private static class ModuleManagerHolder {
private static final ModuleManager instance = new ModuleManager();
}
public static ModuleManager getInstance() {
return ModuleManagerHolder.instance;
}
public void init(ModuleOptions options) {
if (this.options == null && options != null) {
this.options = options;
}
}
public ModuleOptions getOptions() {
return options;
}
public boolean hasModule(String key) {
return options.hasModule(key);
}
}
複製代碼
ModuleOptions就是具體管理那些包含那些模塊的配置。該類是在App或者是測試module獨立運行(後面提到)的時候進行初始化。例如:bash
public class CustomApplication extends BaseApplication {
@Override
public void onCreate() {
super.onCreate();
initARouter();
}
private void initARouter() {
if (LG.isDebug) {
ARouter.openLog();
ARouter.openDebug();
ARouter.printStackTrace();
}
ARouter.init(this);
ModuleOptions.ModuleBuilder builder = new ModuleOptions.ModuleBuilder(this)
.addModule(IHomeProvider.HOME_MAIN_SERVICE, IHomeProvider.HOME_MAIN_SERVICE)
.addModule(IModule1Provider.MODULE1_MAIN_SERVICE, IModule1Provider.MODULE1_MAIN_SERVICE)
.addModule(IModule2Provider.MODULE2_MAIN_SERVICE, IModule2Provider.MODULE2_MAIN_SERVICE)
.addModule(IModule4Provider.MODULE4_MAIN_SERVICE, IModule4Provider.MODULE4_MAIN_SERVICE)
.addModule(IModule5Provider.MODULE5_MAIN_SERVICE, IModule5Provider.MODULE5_MAIN_SERVICE);
ModuleManager.getInstance().init(builder.build());
}
}
複製代碼
這樣子就完成了對改App或者是module的管理。網絡
咱們使用一個ServiceManager,用來獲取不一樣模塊的服務,即Provider。安裝ARouter的文檔,咱們經過繼承IProvider,編寫一個對應模塊的接口,提供接口方法,在對應模塊實現該Provider。而後該Provider咱們就是在ServiceManager裏面進行管理和獲取。好比: home模塊實現一個IHomeProvider,實現類是HomeProvider。數據結構
//接口
public interface IHomeProvider extends IBaseProvider {
//Service
String HOME_MAIN_SERVICE = "/home/main/service";
//開屏
String HOME_ACT_SPLASH = "/home/act/splash";
//home主頁
String HOME_ACT_HOME = "/home/act/home";
String HOME_TABTYPE = "home_tab_type";
void toast(String msg);
void selectedTab(Activity activity,int position);
}
//實現類
@Route(path = IHomeProvider.HOME_MAIN_SERVICE)
public class HomeProvider implements IHomeProvider {
private Context context;
@Override
public void init(Context context) {
this.context = context;
}
@Override
public void toast(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
@Override
public void selectedTab(Activity activity,int position) {
if (activity instanceof HomeActivity) {
((HomeActivity) activity).selectedTab(position);
}
}
}
複製代碼
而後在ServiceManager中,app
//也可使用自動注入,這裏是手動發現而且調用
public IModule1Provider getModule1Provider() {
return module1Provider != null ? module1Provider : (module1Provider = ((IModule1Provider) MyRouter.newInstance(IModule1Provider.MODULE1_MAIN_SERVICE).navigation()));
}
複製代碼
咱們對本Project的全部服務進行管理。而後,在base當中,提供不一樣的Service,對Provider進行調用,同時提供Intent方法,去啓動不一樣模塊的Activity,好比:框架
//管理調用Provider的某一個特定模塊的Service
public class HomeService {
private static boolean hasModule() {
return ModuleManager.getInstance().hasModule(IHomeProvider.HOME_MAIN_SERVICE);
}
public static void selectedTab(Activity activity, int position) {
if (!hasModule()) return;
ServiceManager.getInstance().getHomeProvider().selectedTab(activity, position);
}
}
//管理該module的Activity跳轉
public class HomeIntent {
private static boolean hasModule() {
return ModuleManager.getInstance().hasModule(IHomeProvider.HOME_MAIN_SERVICE);
}
public static void launchHome(int tabType) {
//HomeActivity
MyBundle bundle = new MyBundle();
bundle.put(IHomeProvider.HOME_TABTYPE, tabType);
MyRouter.newInstance(IHomeProvider.HOME_ACT_HOME)
.withBundle(bundle)
.navigation();
}
}
複製代碼
通過這兩個,咱們就已經基本完成了項目組件化。可是對於組件化,咱們還有一個特色,就是每個module都是能夠獨立運行的,方便開發和調試。那麼,咱們應該怎麼弄?maven
ext {
//...版本號以及arr管理
//home是不是做爲模塊,true的時候是,false的時候能夠獨立運行,ps名字有點不對,不想改了ORZ
isMouleDebugHome = true;
//module1是不是做爲模塊,true的時候是,false的時候能夠獨立運行
isModule1Debug = true;
}
複製代碼
而後,在跟build.gradle第一行中apply 進去。
apply from: "config.gradle"
複製代碼
而後,使用sourceSets對代碼進行管理,配置debug和release的代碼,module1的結構以下
if (rootProject.ext.isModule1Debug) {
apply plugin: 'com.android.library'
} else {
apply plugin: 'com.android.application'
}
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode 101
versionName "1.0.1"
if (!rootProject.ext.isModule1Debug) {
applicationId "com.github.io.liweijie.lib1"
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [moduleName: project.getName()]
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
if (!rootProject.ext.isModule1Debug) {
manifest.srcFile 'src/debug/AndroidManifest.xml'
java.srcDir 'src/debug/java/'
res.srcDirs=['src/debug/res']
} else {
manifest.srcFile 'src/release/AndroidManifest.xml'
java.srcDir 'src/release/java/'
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile project(':base')
testCompile 'junit:junit:4.12'
annotationProcessor rootProject.ext.dependencies["aroutercompiler"]
}
複製代碼
這裏須要注意的問題是,debug和relase的清單都須要聲明須要的activity以及其餘組件。debug中還應該配置Application,進行ARouter的初始化。 通過這樣子,咱們的每個module都是能夠獨立運行的模塊了。通常而言,release實際上是沒有什麼東西的,由於release須要的就是咱們module自己須要的業務邏輯實現代碼,他是做爲library去使用的,看本身項目是否須要配置relase。 在本項目中,修改對應的config.gradle中的值就可使得module1和home獨立運行或者是做爲lib添加。 最終結果如圖:
App獨立運行:
App2獨立運行:
home獨立運行:
module1獨立運行:
最近在作公司的App,和同事一塊兒把負責的App組件化了,在這個過程當中有一些坑跟你們分享一下,避免你們再踩。
項目GitHub地址:ModularSample 本文若有什麼寫的錯誤的,請你們指正,一塊兒進步。