前面的 Activity、Service、Receiver 都是系统先启动一个宿主组件,然后我们把请求转给插件。
ContentProvider 不太一样。
它经常在进程启动阶段就被系统创建,而且还有 authority 这一套机制。
所以 Provider 是这个轻量框架里最值得单独讲的一部分。
1. 最简单的 Provider
插件可能有:
1 | public class PluginProvider implements PluginContentProvider { |
Manifest:
1 | <provider |
但因为 APK 没安装,这个 authority 对系统来说不存在。
2. ProxyProvider
宿主注册一个 Provider:
1 | <provider |
外部访问:
1 | content://com.demo.plugin.provider/xxx |
不能直接交给系统,因为系统只认识宿主 Provider。
所以更简单的教学方案是统一使用宿主 authority:
1 | content://com.demo.host.plugin/pluginA/xxx |
ProxyProvider 根据第一段路径找到对应插件。
3. Provider 内部路由
1 |
|
这样就把 Provider 变成了一个路由器。
4. insert/update/delete
其他方法也是一样:
1 | query |
全部从 ProxyProvider 转发给插件对象。
5. 为什么不能简单做到完全透明
如果你要求:
1 | content://com.demo.plugin.provider/xxx |
这个 URI 完全不改,系统还要在插件没有安装的情况下找到 Provider,那么就要更深入系统的 Provider 注册和 AMS/ActivityThread 相关机制。
这已经不是一个“最轻量”框架应该碰的地方了。
所以这里建议明确区分两种目标:
教学版
统一 authority:
1 | content://host.plugin/<plugin>/<path> |
优点是简单、稳定、代码少。
深度兼容版
尝试让插件原始 authority 对外表现得像真实安装的 Provider。
这通常需要处理系统内部 Provider 注册流程,Android 版本升级后也很容易失效。
6. Provider 的启动问题
还有一个坑。
如果宿主启动的时候 Provider 已经被系统创建,那么 ProxyProvider 可以在 onCreate() 中初始化插件管理器。
但插件 Provider 不应该真的要求系统帮它创建。
也就是说:
1 | 系统创建 ProxyProvider |
而不是:
1 | 系统创建 PluginProvider |
后者系统根本做不到,因为插件没有安装。
7. 到这里四大组件基本闭环
现在可以把四种组件放在一起:
1 | Activity -> ProxyActivity |
不过真正使用时,还缺一个统一的 PluginManager 和组件路由层。
下一篇把这几个东西真正拼起来。