GitHub - luckybilly/AndroidComponentizeLibs: 多个维度对比一些有代表性的开源android组件化开发方案
开源时间
2017-11
2017-9
2017-1
2016-12
2016-9
2016-4
介绍文章
wiki
Android彻底组件化方案实践
Android架构思考(模块化、多进程)
开源最佳实践:Android平台页面路由框架Arouter
聚美组件化实践之路
ActivityRouter路由框架:通过注解实现URL打开Activity
通信机制
组件总线
路由 + 接口下沉
组件总线
路由 + 接口下沉
路由 + 接口下沉
路由 + 静态方法
activity跳转
✅
✅
✅
✅
✅
✅
是否支持降级处理
✅
❌
✅
✅
✅
✅
activity变量自动注入
❌
1. 通过apt生成自动注入代码
2. 在onCreate中调用
2. 在onCreate方法中调用
建议使用统一的组件调用方式 仅支持Activity 仅支持Activity 仅支持Activity 支持Activity/Fragment 仅支持Activity 调用方式(页面跳转) 同步直接返回结果或异步回调结果:
或
.route(MainActivity.this, RouterRequest.obtain(MainActivity.this)
.domain("com.spinytech.maindemo:music")
.provider("music")
.action("shutdown"));
String temp = response.getData(); onActivityResult返回结果:
TrasnformAPI + javassist将IApplicationLike的注册代码生成到自定义application.onCreate方法中,无需手动维护组件列表 未实现自动注册,
1. Action列表在其所属的Provider中注册
2. Provider在其所属的ApplicationLogic中注册
3. ApplicationLogic在主app的Application中注册 新版本(1.3.0)开始支持通过插件完成路由注册
1. apt生成各module的路由表
2. TrasnformAPI + ASM扫描路由表并注册到LogisticsCenter中,无需手动维护组件列表 1. apt生成各module的路由表pkg.RouterRuleCreator类
2. 在ComponentPackages中定义所有RouterRuleCreator的包名
3.在BaseApplication中反射所有的包名找到所有路由表RouterRuleCreator
4. 需要手动维护ComponentPackages类中的包名列表 1. apt生成各module的路由表
2. apt在application的module通过Modules注解生成RouterInit进行注册
3. 需要手动维护Modules注解中的组件列表 组件单独运行的方式 切换library/application方式编译,提供2种方式:
1. module/build.gradle中切换
2. 在local.properties中切换
好处是所有组件调试时包名相同,能满足分享及地图等第三方SDK对包名的要求 切换library/application方式编译,框架本身没有提供切换方式,开发者自行解决 跨app组件调用支持 ✅ ❌ ✅ ❌ ❌ ✅ 跨app调用开关及权限设置 ✅ / ❌ / / ❌ 组件app运行时调用其它组件 组件同时安装在设备上即可,实际开发中一般是当前正在开发的组件和主app中的组件互相调用.
通过广播 + Service + LocalSocket实现,没有UrlScheme调用时弹出的选择框 将需要调用的组件一起打包才能调用 组件同时安装在设备上即可,实际开发中一般是当前正在开发的组件和主app中的组件互相调用.
通过AIDL实现 一起打包或者通过urlScheme来统一转发 将需要调用的组件一起打包才能调用 UrlScheme原生支持跨app调用,组件同时安装在设备上即可
通过中介Activity转发:RouterActivity 组件依赖隔离 无需依赖、完全隔离 通过插件实现只在打apk包时才添加依赖,编码期间不能直接调用其它组件的代码,想知道如何实现可以戳这里 无需依赖、完全隔离 未隔离 未隔离 无需依赖、完全隔离 AOP支持 拦截器 + 组件内部Action进行AOP ❌ 组件内部Action进行AOP 拦截器AOP ❌ ❌ 拦截器 ✅ ❌ ❌ ✅ ✅ ❌ 组件调用的超时设置 ✅ ❌ ❌ ❌ ❌ ❌ 组件调用的取消 ✅ ❌ ❌ ❌ ❌ ❌ 动态注册/注销组件 ✅ ✅ ❌ ❌ ❌ ❌ 特点 1. 可以跨app调用,初期改造时即可单独编译组件运行
2. 提供统一的组件调用及实现方式(不管是否跨app调用、页面跳转、服务调用、同步/异步调用)
3. 组件自动注册,无需维护
4. 提供了ActionProcessor按需加载的支持 1. 编码期间组件依赖通过插件进行隔离,避免直接调用其它组件的代码
2. 提供了兼容ARouter的方案
3. 组件自动注册,无需维护 1. 可以跨app、app内跨进程调用
2. 组件运行在各自进程中,单独运行与联合打包切换时需要修改进程名称
3. 组件需指定同步实现还是异步实现,调用组件时统一拿到RouterResponse作为返回值,可以自行决定同步还是异步方式调用RouterResponse.getData()来获取结果,但异步获取时需要自己维护线程 1. 阿里出品,使用者众多,QQ群里交流比较活跃
2. 支持分级按需加载
3. 是一个路由框架,并不是完整的组件化方案,可作为组件化架构的通信引擎 组件module可以始终以library方式编译,由统一的app壳子来安装调试,不需要切换library/application编译方式、避免了第三方SDK需要指定包名的问题、自定义权限重复导致安装冲突的问题、误操作导致apk upload到maven仓库的问题等 1. 业内最早的组件化支持库
2. 通过注解静态方法的方式暴露服务 组件定义代码侵入性 新增IComponent接口的实现类来定义组件,侵入性低 注解定义路由及参数自动注入,侵入性高 新增接口实现类,侵入性低 注解定义路由及参数自动注入,侵入性高 注解定义路由,侵入性高 注解定义路由,侵入性高 组件调用代码侵入性 高 高 高 高 高 高 混淆配置 无 所有下沉接口、框架中相关接口的实现类等
2. 在onCreate中调用
AutowiredService.Factory.getInstance().create().autowire(this);或者继承BaseActivity
❌
1. 通过apt生成解析参数的代码2. 在onCreate方法中调用
ARouter.getInstance().inject(this);实现自动注入
❌
❌
startActivityForResult
支持Activity/Fragment,但不建议使用建议使用统一的组件调用方式 仅支持Activity 仅支持Activity 仅支持Activity 支持Activity/Fragment 仅支持Activity 调用方式(页面跳转) 同步直接返回结果或异步回调结果:
CCResult result = CC.obtainBuilder("ComponentA").build().call();或
String callId = CC.obtainBuilder("ComponentA").build().callAsync(new IComponentCallback(){...});
onActivityResult返回结果:UIRouter.getInstance().openUri(getActivity(), url, bundle);
RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()).route(MainActivity.this, RouterRequest.obtain(MainActivity.this)
.domain("com.spinytech.maindemo:music")
.provider("music")
.action("shutdown"));
String temp = response.getData(); onActivityResult返回结果:
ARouter.getInstance().build("/test/activity").navigation();
onActivityResult返回结果:Router.create(url).open(context);
onActivityResult返回结果:Routers.open(context, url);
调用方式(调用服务)
与页面跳转相同
Router.getInstance().getService(ReadBookService.class.getSimpleName())
与页面跳转相同
ARouter.getInstance().navigation(HelloService.class).sayHello();
PipeManager.get(LoginPipe.class).logout();
与页面跳转相同
组件向外提供服务
与页面跳转一致,在IComponent中实现
接口下沉到base中,组件中实现接口并在IApplicationLike中添加代码注册到Router中
与页面跳转一致,实现一个对应的Action并在其所属的Provider中注册即可
接口继承IProvider并下沉到base中,组件中实现接口并通过注解来暴露服务
接口下沉到base中,组件中实现接口并在ApplicationDelegate中向接口管理类注册PipeManager.register(CorePipe.class, new CorePipeImpl());
在静态方法上加注解来暴露服务,但不支持返回值,且参数固定位(context, bundle)
Fragment组件化支持
在IComponent中实现,并支持后续Fragment内部功能调用
调用服务的方式实现,未支持后续Fragment内部的功能调用
不支持
调用服务的方式实现,未支持后续Fragment内部的功能调用
调用服务的方式实现,未支持后续Fragment内部的功能调用
不支持
组件自动注册方案
TrasnformAPI + ASM扫描组件类(IComponent接口实现类)并注册到ComponentMananger中,无需手动维护组件列表
apt生成各module的路由表TrasnformAPI + javassist将IApplicationLike的注册代码生成到自定义application.onCreate方法中,无需手动维护组件列表 未实现自动注册,
1. Action列表在其所属的Provider中注册
2. Provider在其所属的ApplicationLogic中注册
3. ApplicationLogic在主app的Application中注册 新版本(1.3.0)开始支持通过插件完成路由注册
1. apt生成各module的路由表
2. TrasnformAPI + ASM扫描路由表并注册到LogisticsCenter中,无需手动维护组件列表 1. apt生成各module的路由表pkg.RouterRuleCreator类
2. 在ComponentPackages中定义所有RouterRuleCreator的包名
3.在BaseApplication中反射所有的包名找到所有路由表RouterRuleCreator
4. 需要手动维护ComponentPackages类中的包名列表 1. apt生成各module的路由表
2. apt在application的module通过Modules注解生成RouterInit进行注册
3. 需要手动维护Modules注解中的组件列表 组件单独运行的方式 切换library/application方式编译,提供2种方式:
1. module/build.gradle中切换
ext.runAsApp=trueOrFalse2. 在local.properties中切换
moduleName=trueOrFalse(推荐使用的方式,不会提交到代码仓库中)
切换library/application方式编译,在module/gradle.properties中切换isRunAlone=trueOrFalse
切换library/application方式编译,框架本身没有提供切换方式,开发者自行解决
切换library/application方式编译,框架本身没有提供切换方式,开发者自行解决
组件module始终以library方式编译,额外提供app壳子,可以按需将多个组件依赖进来一起打包。好处是所有组件调试时包名相同,能满足分享及地图等第三方SDK对包名的要求 切换library/application方式编译,框架本身没有提供切换方式,开发者自行解决 跨app组件调用支持 ✅ ❌ ✅ ❌ ❌ ✅ 跨app调用开关及权限设置 ✅ / ❌ / / ❌ 组件app运行时调用其它组件 组件同时安装在设备上即可,实际开发中一般是当前正在开发的组件和主app中的组件互相调用.
通过广播 + Service + LocalSocket实现,没有UrlScheme调用时弹出的选择框 将需要调用的组件一起打包才能调用 组件同时安装在设备上即可,实际开发中一般是当前正在开发的组件和主app中的组件互相调用.
通过AIDL实现 一起打包或者通过urlScheme来统一转发 将需要调用的组件一起打包才能调用 UrlScheme原生支持跨app调用,组件同时安装在设备上即可
通过中介Activity转发:RouterActivity 组件依赖隔离 无需依赖、完全隔离 通过插件实现只在打apk包时才添加依赖,编码期间不能直接调用其它组件的代码,想知道如何实现可以戳这里 无需依赖、完全隔离 未隔离 未隔离 无需依赖、完全隔离 AOP支持 拦截器 + 组件内部Action进行AOP ❌ 组件内部Action进行AOP 拦截器AOP ❌ ❌ 拦截器 ✅ ❌ ❌ ✅ ✅ ❌ 组件调用的超时设置 ✅ ❌ ❌ ❌ ❌ ❌ 组件调用的取消 ✅ ❌ ❌ ❌ ❌ ❌ 动态注册/注销组件 ✅ ✅ ❌ ❌ ❌ ❌ 特点 1. 可以跨app调用,初期改造时即可单独编译组件运行
2. 提供统一的组件调用及实现方式(不管是否跨app调用、页面跳转、服务调用、同步/异步调用)
3. 组件自动注册,无需维护
4. 提供了ActionProcessor按需加载的支持 1. 编码期间组件依赖通过插件进行隔离,避免直接调用其它组件的代码
2. 提供了兼容ARouter的方案
3. 组件自动注册,无需维护 1. 可以跨app、app内跨进程调用
2. 组件运行在各自进程中,单独运行与联合打包切换时需要修改进程名称
3. 组件需指定同步实现还是异步实现,调用组件时统一拿到RouterResponse作为返回值,可以自行决定同步还是异步方式调用RouterResponse.getData()来获取结果,但异步获取时需要自己维护线程 1. 阿里出品,使用者众多,QQ群里交流比较活跃
2. 支持分级按需加载
3. 是一个路由框架,并不是完整的组件化方案,可作为组件化架构的通信引擎 组件module可以始终以library方式编译,由统一的app壳子来安装调试,不需要切换library/application编译方式、避免了第三方SDK需要指定包名的问题、自定义权限重复导致安装冲突的问题、误操作导致apk upload到maven仓库的问题等 1. 业内最早的组件化支持库
2. 通过注解静态方法的方式暴露服务 组件定义代码侵入性 新增IComponent接口的实现类来定义组件,侵入性低 注解定义路由及参数自动注入,侵入性高 新增接口实现类,侵入性低 注解定义路由及参数自动注入,侵入性高 注解定义路由,侵入性高 注解定义路由,侵入性高 组件调用代码侵入性 高 高 高 高 高 高 混淆配置 无 所有下沉接口、框架中相关接口的实现类等
-dontwarn com.spinytech.**
框架中的所有类及框架相关接口的实现类
所有RouterRuleCreator类
框架中的所有类
老项目改造成本评估
低
一般
高
一般
高
低
方案使用的学习成本评估
低
一般
高
一般
一般
一般
后续维护成本评估
低
一般
高
低
一般
一般
QQ群
686844583
693097923
无
592278657 / 336755078
108895031
无