组件化开发的新选择【AutoService】

  • 内容
  • 评论
  • 相关

前言

在我们进行组件化开发的时候,最需要解决的就是组件间通信,一般来说,我们一般将一个组件分为两个工程,一个只包含组件对外提供的接口另一个则是实现,当然,为了彻底解耦,我们应该让外部调用者完全感知不到实现,在开发时候时候也无法引用到实现中的其他方法,这就需要我们在编译期间动态添加依赖,由于本篇博客的重点不在这里,所以不多介绍,具体可以查看这里

通过上面的介绍我们知道,当开发的时候,我们只能知道接口而不能知道实现类,所以无法访问,当然国内不缺少牛人,所以解决方案大致有以下几种。

1、遍历dex文件找到实现类并动态注册

代表:ARouter默认实现

缺点:遍历dex可能由于Android版本的不同导致找不到实现类并且会增加耗时,并且使用的反射去实例化对象

2、修改字节码动态插入

代表:AutoRegister

缺点:可能会导致打包慢

优点:兼容性好一劳永逸,性能高

3、使用AutoService+ServiceLoader,本篇博客主要就是介绍此方案

缺点:使用的反射去实例化对象

优点:易配置,易调试,上手快

AutoService

AutoService是Google开源的用来方便生成符合ServiceLoader规范的开源库,使用非常的简单。

Github地址:https://github.com/google/auto/tree/master/service

引入:

首先定义一个接口

然后使用AutoService注解在实现上面声明即可。下面的例子展示了同时声明多个接口

然后就轮到我们的ServiceLoader出场了

这样我们就能获得具体的实现类了,我们也可以将此段逻辑封装为一个工具类。

原理

在我们使用AutoService注解以后到底发生了什么呢?

首先会在我们的apk的META-INF文件夹中新建一个services文件夹,然后在下面为我们生成一个配置文件(app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes\META-INF\services\)。

文件名为接口的全包名+类名,里面的内容为实现类的全包名+类名,一行为一个实现类,可以同时有多行

这就是AutoService为我们做的全部的处理了。类的加载其实使用的java的类加载机制。使用ClassLoader读取到META-INF\services下指定文件的内容,然后使用反射去实例化对象。具体的可以自行查看ServiceLoader的源码。

其他

1、如果项目中开启了混淆,那么需要保证实现类不被删除以及类名不被混淆,但是成员变量可以被混淆

2、同一个接口可以有多个实现,多个实现也可以在不同的Module中,Android Studio会自动为我们合并生成的文件的内容

3、最好将Service加载封装起来,便于切换实现

4、ServiceLoader不会为我们缓存对象,每一次使用ServiceLoader都会创建一个实例,这点需要注意

参考地址

https://mp.weixin.qq.com/s/AyR4irlka77aJ8KdEdYbrw

https://github.com/google/auto/tree/master/service

 

评论

0条评论

发表评论

邮箱地址不会被公开。