一、背景
还记得上一次分享的模块间通信和调用吗?Android 模块化之路 模块间通信 在这个文章里面,我们说到,如果涉及到跨进程,那我们可以用 AIDL 的方式来解决跨进程的问题。
但用户的一些质疑声也来了:
- 我还是一个小 App,不用跨进程,我不是淘宝,不是微信,用 AIDL 太重了点吧?
- AIDL 只支持基本类型的入参和出参,并且还是有点学习成本的,有没有简单一 点的方案呢?就是那种一点就透,一用就爽,一爽就开心的奇淫技巧?
好吧,那就再介绍另外一种模块间通信的方式。
二、迷你模块间调用
和前面提到的 AIDL 的方式一样,也是通过面向接口编程,子模块增加接口层,然后具体的实现不再通过AIDL来实现,而是通过最简单粗暴的Class.forName();
在 WEB 端开发,Spring 定义出 Service和 ServiceImpl,通过 XML 文件定义bean的实现。
我们在这里也采用同样的方式。
首页我们祭出我们的基类:
上面的是一个接口类,所有模块接口声明都继续此接口。
比如我们定义 IShopcartService 接口代码如下:
可以看到上面就是最普通的 JAVA 写法,解决了 AIDL 的出参和入参要实现序列化麻烦的问题。
我们再来看一下具体的实现:
然后就是怎么获取这个Service的实例了,调用代码如下:
那 Services 中的代码又是如何实现的呢?
讲到这里,基本这个小巧的设计实现和思路就完成了。
但还有两个问题需要解决:
-
实例什么时候初始化? App 启动时就直接实例化好还是用到的时候再newInstance呢? 上面的实现是放到用到的时候再初始化。
-
实例的映射关系存到哪里? 放到asset里面,还是自己读 xml文件,还是放到raw里面,弄一个properties文件呢?我这里的实现是读 RAW,大家可以自行改造。
源码地址:https://github.com/ssevening/AndroidAidlExample
三、我们再说进阶
看到上面的内容,然后肯定又要说了,擦,就这么简单?一点逼格也没有啊?怎么样增加一点逼格呢?这里给大家抛几个问题,也是几个方向,完成了这几个问题后,你的逼格也就上去了。
- 要自己来维护接口和实现类的映射,有点 Low,考虑机器自动生成吧,那就是去看看运行时注解。
- 写在raw中的文件,一是多模块化的话,只有在主工程中定义这个 RAW 文件,有没有办法放到子模块中定义呢?
- 怎么样解决规则文件的批写错误呢?
- 如果遇到获取服务失败,有没有及时发现和报警的功能?
- 有没有能力做到 ABTest 动态替换呢?比如新发布一个实现类,让新类和旧类同时运行,但又可以在线上动态替换?
- Service中怎样进行一些环境变量的区分或mock呢?比如 DEBUG 环境下打印日志?
大家多想一想,然后把上面的问题解决了,一个高逼格的 模块间调用框架就出来了。
最后,提醒一下,上线前的混淆不要忘记 keep 所有 extends IJavaService 的类噢。
四、一些总结
模块间通信扯到这里,基本上分为三个阶段:
- 创业型 App,自建 Map 来维护服务关系,最简单,也最稳定。
- 搞一些高科技,然后把运行时注解也搞上,自动生成,同时完成路由,比如阿里的:ARouter 也是个不错的方案。
- 要跨进程,要跨应用调用,这个时候,就只有 AIDL 的方案了,但有成本,第一种自建 Map 的方式,可以轻松切换到 AIDL 的方式,而如果是ARouter的方式,估计切到 AIDL 就不太好了。当然,如果都要用到 AIDL 的时候,创业必然成功,团队必然壮大!也不在乎重构一把了!
下一篇,接着扯Android 模块化过程中,还有哪些问题需要解决和面对。
赛文市场营销