在学习模块化的过程中,也在不断思考,同时和一些模块化方案的作者进行了一些交流,记录下自己的一些心得体会。
为什么要使用模块化,使用什么样的模块化?
我认为使用模块化的原因,从代码层面考虑精髓就是解耦合,从工程项目角度考虑,是为了分组协同,隔离,甚至动态发布这些。所以重点来了,在考量是否需要使用模块化的时候,得首先考虑,代码是否耦合严重,或者是否需要规模分组开发,如果是个人开发者,或者超小团队,引入模块化方案,可能带来效率的降低,并且可能引入的bug,可能比带来的收益都要低。其次,使用什么样的模块化。前段时间,阿里开源了Atlas
,然后对于大部分中小型项目而言,Atlas
并不是一种好的选择,过于复杂和厚重,可能小型的路由方案,就可以实现全部需求。引入大型项目的解决方案,反而带来效率的降低。
模块化框架该如何设计
在了解模块化的过程中,除了走读各种方案代码,自己写个简单的路由框架以外,我也在思考模块化方案的设置思路。
- 当前两种方案的优劣
在之前的文章中也提到,当前的模块化方案中,一种是靠编译期的注解处理处理器生成路由表。一种是靠代码运行时的反射,在代码运行阶段,通过处理注解,取得路由跳转关系,比如LiteRouter。 相比前一种方案,个人觉得这种方案,还是存在一些问题。首先,反射存在性能开销,这类方案基本都是仿照Retrofit的思路在设计,但是Retrofit毕竟是个网络请求方案,反射带来的性能开销造成的时间,和网络请求的时间相比,几乎可以忽略不计,但是,对于组件跳转的场景,这部分性能开销,可能多少会有一些影响。不过这种设计思想的精妙的确值得肯定。
- 模块化设置时的细节
之前Arouter的作者,在演讲中也说了,模块化方案,作为一个App的底层架构,应该需要足够的稳定,我个人也很认同此观点。这段时间看了几种模块化方案的源码细节,其中的一些细节,印象深刻。
比如对 Activity 细节的处理。
// Set flags.
int flags = postcard.getFlags();
if (-1 != flags) {
intent.setFlags(flags);
} else if (!(currentContext instanceof Activity)) { // Non activity, need less one flag.
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
比如 对线程的处理
// Navigation in main looper.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (requestCode > 0) { // Need start for result
ActivityCompat.startActivityForResult((Activity) currentContext, intent, requestCode, postcard.getOptionsBundle());
} else {
ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle());
}
if ((0 != postcard.getEnterAnim() || 0 != postcard.getExitAnim()) && currentContext instanceof Activity) { // Old version.
((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim());
}
}
});
比如在注解编译器中完备的日志系统等。
这些设计,虽然都是细小的点,但是在对于增加代码稳定性和可维护性方面,均有很多提升。
通过这些点,我个人的体会是,一个框架的设计和功能设计还是有很大不同的。框架的设计,除了框架功能的完成,容错,异常,错误收集这些点同样应该在优先级比较高的位置。
模块化的衍生
在思考模块化的过程中,也在想是否和其他方案结合。记录下思路。当然都是个人见解和思路。
- 与配置中心(应用中心)结合
功能复杂的App,每个功能入口的顺序可能会不断变化,如果纯用native实现功能的话,Activity的代码可以预埋在本地,同时生成路由关系,在合适的时机从服务器拉取配置,配置中携带了功能模块的图标等信息和一个URL,然后根据URL完成功能跳转。可以实现一个比较最简易的动态化方案。
- 运用跳转拦截进行降级
如果跳转路径Activity中发生了Crash,目标Activity中数据显示异常时候,可以通过一些策略触发降级,通过H5 App的方式来实现功能。之前看过一一些自动恢复的框架,可以通过这个框架和路由方案的集合设计一种思路,当通过URL跳转出现Crash时,把自动恢复的流程替换为直接通过URL进行降级,打开web容器,启动H5 App或者web的错误页面,增强App的容错和体验。
- 。。。
如今模块化方案,已经初步成熟,并且不断演进之中,相信很多值得探索的地方,随着一些新方案的出现和Android系统的升级,对于模块化方案,后续海需要不断学习研究深入。