完整組化件和插件化可以參考我的github項目,已經用在線上項目中
組件化: 就是將一個完整的功能拆分成多個子模塊,而每個子模塊可以獨立編譯和運行,也可以任意的組合成一個新的APP
優勢:
團隊開發過程中方便項目管理,它分工非常明確互不干擾,不存在甩鍋.
組件與組件之間他們不相互依賴卻可以相互交互,任意組合,高度解耦.
可以分模塊打包,分模塊測試,可以統一版本的管理(比如buildtools)
比如一個產品模塊,我們想要替換成另個一個產品模塊,則可以直接砍掉之前的產品,直接切換成新的產品模塊
二 Phone Model 和Android Model區別 切換
Phone Mode: 新建出可以獨立運行的模塊,可以看成是一個app,
配置爲: apply plugin: 'com.android.application',他有applicationId
Android Model: 新建出一個安卓庫,不能獨立運行,
配置爲: apply plugin: 'com.android.library',他沒有applicationId
如何相互切換
需要配置一個boolean參數 比如isRelease
if (isRelease) {
apply plugin: 'com.android.library'
} else {
apply plugin: 'com.android.application'
}
...
defaultConfig {
if (!isRelease) {
applicationId xxx.xxx.xxx
}
...
}
只要改變isRelease就可以切換,如果是PhoneModel,得把applicationId 加上
組件化臨時開發的代碼的動態隔離
sourceSets {
main {
if (!isRelease) {
//如果是組件化模式時,需要獨立運行時
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
//如果是集成化時,整個項目打包apk
manifest.srcFile 'src/main/AndroidManifest.xml'
java {
//release時,debug目錄下文件不需要合併到工程裏
exclude '**/debug/**'
}
}
}
}
組件化之間的交互(比如跳轉,傳參)
比如: A模塊需要跳轉到B模塊怎麼處理
方式一: EventBus: 缺點 EventBean會很多在一對一的情況下, 如果是一對多的話,容易出現混亂,難以維護
方式二: 反射, 缺點 反射技術也可以成功,但是維護起來有點高,特別是高版本對@hide的限制
方式三: 隱式跳轉,維護好,但是有點麻煩,需要維護Manifest中的action
方式四: 廣播,7.0後需要動態註冊發送
方式五: 類加載, 需要準確的全類名路徑,維護成本高且容易出現人爲的失誤,有時調試bug麻煩
...
實現方案一: 類加載機制跳轉
try {
//需要準確的全類名路徑
Class targetClass = Class.forName("com.ancely.fyw.login.Login_MainActivity");
Intent intent = new Intent(this,targetClass);
intent.putExtra("name","ancely");
startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
實現方案二:全局Map記錄信息
在公共庫定義一個PathBean對象,和一個PathBean管理器
public class PathBean {
private String path;//跳轉目標字符串key 比如/app/MainActivity
private Class clazz;//跳轉的目標對象 MainActivity.class
}
/*
* @描述: 全局路徑管理器(根據組模塊分類)
*/
public class PathBeanManager {
/**
* key 組的唯一標識, value: 組裏面需要的一些類的路徑
*/
private static Map<String, List<PathBean>> groupMap = new HashMap<>();
public void joinGroup(String groupName, String pathName, Class<?> clazz) {
List<PathBean> list = groupMap.get(groupName);
if (list == null) {
list = new ArrayList<>();
list.add(new PathBean(pathName, clazz));
groupMap.put(groupName, list);
} else {
for (PathBean pathBean : list) {
if (!pathName.equals(pathBean.getPath())) {
list.add(new PathBean(pathName, clazz));
groupMap.put(groupName, list);
}
}
}
}
public static Class<?> getTargetClass(String groupName, String pathName) {
List<PathBean> list = groupMap.get(groupName);
if (list == null) {
return null;
}
for (PathBean pathBean : list) {
if (pathName.equalsIgnoreCase(pathBean.getPath())) {
return pathBean.getClazz();
}
}
return null;
}
}
然後在每個Application裏面的initializa方法裏面進行初始化,
PathBeanManager.joinGroup("app","/app/MainActivity",MainActivity.class);
並且在主Application裏面對組Application進行類的創建,在onCreate方法裏面調用下面方法
@Override
public void initializa(Application app) {
appication = (App) app;
for (String component : AppConfig.COMPONENTS) {
try {
Class<?> clazz = Class.forName(component);
Object obj = clazz.newInstance();
if (obj instanceof IAppComponent) {
((IAppComponent) obj).initializa(this);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
還得配置AppConfig
public class AppConfig {
public static final String[] COMPONENTS = {
"luckly.ancely.com.homemodule.HomeApp",
"luckly.ancely.com.loginmodule.LoginApp",
"luckly.ancely.com.network.NetWorkApp",
"com.ancely.compress.CompressApp"};
}
最後跳轉,這就是路由跳轉
Class<?> targetClass = PathBeanManager.getTargetClass("app", "/app/MainActivity");
Intent intent = new Intent(this,targetClass);
startActivity(intent);