完整组化件和插件化可以参考我的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);