ServiceLoader
最近看滴滴开源的Dokit库源码(官网地址),发现Dokit使用了ServiceLoader
和AutoService
库实现的组件/插件机制,就研究了一下,感觉平时如果开发一个SDK框架应该用得上。
ServiceLoader可以理解为是一个接口或类的加载器,通过接口或抽象类能够找到实现该接口或抽象类的子类。
ServiceLoader的使用需要以下几个步骤:
- 创建一个接口文件
- 在resources资源目录下创建META-INF/services文件夹
- 在services文件夹中创建文件,以接口全名命名
- 创建接口实现类
这样使用比较麻烦,而google提供了一个库来简化这些操作,那就是AutoService
库。
使用AutoService库
开源库地址:AutoService
1、添加该库依赖:
implementation 'com.google.auto.service:auto-service:1.0'
kapt 'com.google.auto.service:auto-service:1.0'
2、创建插件接口IPlugin
interface IPlugin {
void init();
}
3、创建抽象类AbsPlugin并实现IPlugin接口
abstract class AbsPlugin : IPlugin {
}
4、创建插件实现类,需要继承AbsPlugin抽象类和添加AutoService
注解,注解中的参数就是定义的抽象类
@AutoService(AbsPlugin::class)
class LogPlugin : AbsPlugin() {
override fun init() {
Log.e("init: ", "LogPlugin")
}
}
再创建一个插件:
@AutoService(AbsPlugin::class)
class NetworkPlugin : AbsPlugin() {
override fun init() {
Log.e("init: ", "NetworkPlugin")
}
}
5、最后在MainActivity中使用ServiceLoader
来加载抽象类,得到的是继承AbsPlugin的子类实例
// 得到的是继承AbsPlugin的子类实例
val list = ServiceLoader.load(AbsPlugin::class.java, javaClass.classLoader).toList();
list.forEach {
Log.e("onCreate: ", it.toString())
// 执行init方法
it.init();
}
打印结果:
E/onCreate:: com.learn.serviceloader.plugins.LogPlugin@db3bda9
E/init:: LogPlugin