DroidPlugin、dynamic-load-apk、DynamicAPK三种插件化方案的对比

  • Hook:

DroidPlugin和DynamicAPK中都有对android framework进行hook.DroidPlugin中做了大量的hook,主要出于两个目的:1.欺骗系统.2.欺骗插件;DynamicAPK中hook的力度则较小,仅针对插件中的activity对系统Instrument和ContextImpl类进行了hook,且没有做到欺骗插件,所以迁移成本较重。举个例子:插件中调用getPackageName,使用DroidPlugin框架得到的是插件的包名,而DynamicAPK则会得到宿主的包名。

dynamic-load-apk中没有采用hook机制。

  • 进程:

DroidPlugin中做到了进程隔离,即宿主和插件运行于不同的进程之中;dynamic-load-apk和DynamicAPK中,宿主和插件运行于同一进程。

  • ClassLoader:

DroidPlugin和dynamic-load-apk中插件和宿主使用不同的ClassLoader;DynamicAPK中插件和宿主使用同一个ClassLoader,潜在的风险是如果插件和宿主使用了同一个库的两个不同版本,可能回引起crash.

  • so:

DynamicAPK中不支持so;dynamic-load-apk中有针对插件中的so做处理,但是作者在处理的地方指出还存在问题,可能会出bug;DroidPlugin中也有针对so的处理,目前使用GameStore作为插件运行demo是可以正常运行的,但官方文档给出的是目前对于so支持还不理想,也特指了游戏部分。

  • resource:

DynamicAPK中对资源打包工具aapt进行了改造,打包插件的时候需要使用改造过的aapt,同时插件中的资源命名需要follow一些规则,比如不能和宿主及其他插件中的重名,这么做带来的好处就是无论在插件还是宿主中都可以访问到所有资源;DrdoidPlugin和dynamic-load-apk中插件只能访问到自己的资源,也就没有像DynamicAPK中对于资源编译的各种限制。

  • Manifest

DroidPlugin和dynamic-load-apk中都要在manifest中预先占坑,即声明自己的代理activity和service;DynamicAPK需要把插件中的组件在宿主的manifest中原样声明一遍,这样就会对插件的热更新做出一定的限制,如果要插件中加了新的activity,宿主也需要更新。

  • 四大组件:

DroidPlugin中支持插件中的四大组件,但是使用上还是会有一些限制,比如插件中静态的receiver其实是在宿主中动态声明,导致插件中的一些广播(例如开机广播)可能没办法正常工作;DynamicAPK所有组件都需要在宿主的manifest中原样声明一遍,所以理论上也是支持四大组件;dynamic-apk-load不支持receiver和ContentProvider。

  • 迁移成本:

dynamic-load-apk中严重依赖that语法,几乎所有使用到this的地方都需要换成that,迁移成本较重;DynamicAPK中缺乏针对欺骗插件的hook机制,所以apk如果想以插件运行,可能也需要做一些修改,同时插件中相关的资源也有较多的限制,迁移成本较重;DroidPlugin理论上不需要做任何修改,即开发单独的apk和插件使用同一套代码即可,个人觉得实际使用过程中还是需要做一些修改,肯定有一些没有hook或者难以hook的API.

  • 通信:

DynamicAPK和dynamic-load-apk中由于宿主和插件运行在同一个进程,内存共享,所以宿主和插件,插件和插件之间的相互调用比较容易;DroidPlugin的完全隔离使得需要一些跨进程通信的手段完成宿主和插件的相互调用,如Binder,Intent等。

         以上结论为分析源码以及参考一些文档所得,没有经过大量实践,可能存在疏漏,如有问题,请指出。谢谢!

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/121653732