今天我们讲讲Android中的插件化,插件化,指的就是加载本地不存在的外部可执行文件。
大的方向,首先分为两种
1.动态加载so库(其实可以放在外部存储,我们常用的是放在内部存储)
2.classloader动态加载外部可执行文件,如dex,jar,apk
关于动态加载,细分为三种:
第一,简单的动态加载;这种不适用插件的activity。使用插件的fragment,或者只是用dex中的逻辑,或者用代码编写布局的方式替换布局。实现起来比较简单,比较稳定,但是有限制,适用于界面改动小,或者不改动,逻辑sdk,登录注册界面等等。
第二,静态代理activity;这种是使用插件的activity,但是实际上使用的是host的activity。使用插件的activity,需要解决两个问题,
一是生命周期,
关于生命周期,通过在host提前注册好需要的activity,然后拿到插件activity引用(两种方式,通过反射拿到,再则通过把插件activity接口化,通过接口调用的方式,更推荐这种,方便host控制插件),在各个生命周期方法中同步调用。
二是R资源。
关于R资源,需要通过反射拿到AssertManager,调用其addAssertPath,得到Resource资源对象。相当于多维护了一套R资源。实际上,我们平日用的就有两套R资源,应用层的一套,然后系统层的一套。
第三,动态注册activity
关于动态注册activity,他解决生命周期和R资源的方式就更简单了,相当于是通过标准模式启动了一个activity,自然而然该activity就具备了生命周期和R资源。那么这种该如何做呢?
首先,host中,要有一个通用的PluginActivity,当要启动PluginActivity的时候,我们复写ClassLoader的loadClass方法,当要找的事PluginActivity,我们通过DexMaker生成一个TargetActivity extends PluginActivity. 然后return TargetActivity实例。这样就完美解决了生命周期和R资源的问题。
如果插件里面需要有多个activity,如何从TargetActivity中跳转到其他Activity呢,实际上我们知道所有的跳转都会走到startActivityForResult,我们只需要在用DexMaker生成TargetActivity的时候,复写对应的startActivityForResult方法就行了。
现在市面上的各种插件化框架,大多是上面的变形或者组合。下一篇我们将结合实例分析,敬请期待~