Android 插件平台技术 基本介绍和dynamic-load-apk介绍

示例App

目前像支付宝,美团,糯米,手机百度,百度地图等包含多个子业务的app都用了插件平台技术。插件平台所提供的增量更新技术,相信很多app也都包含了,可以使得在app在已经发版的情况下,通过增量更新来解决线上bug,而不需要再次发版。

收益

平台化的好处是,可以将各类子应用像插件一样,放在自己的平台上。可以动态插拔,用起来很方便,很灵活。具体的好处是:

1. 可以进行增量更新。小哥写了个bug,怎么办?用增量更新就可以了。很高端吧。

2. 可以减小包得大小。

3. 可以分组件开发。


方案调研

后面我们会针对dynamicloadapk,Direct-Load-apk等平台解决方案进行介绍。
这里先介绍一下平台化方案需要解决的问题:
1.load apk的问题。你的apk在sd卡上或者data/data底下,那需要load起来才可以跑。

2.load起来之后,需要把apk中得activity跑起来。但是跟以往的activity启动方式不同,被load起来的插件是有activity thread给你服务的,这个问题需要解决。

3.在插件activity运行过程中,需要调用自己的resources,assets等资源文件,而且形式和常规activity一致。

方案一 dynamic-load-apk 简介

github:https://github.com/singwhatiwanna/dynamic-load-apk

下面简单介绍一下这个类库的基本思路,摘取了一些代码来做解释,不是很完整。下面一节会用类图和时序图做详细的解释。(具体的代码还是要靠大家自己去看了)
解决上述三个问题的方法是:
1.用classloader来load apk。

DexClassLoader loader = new DexClassLoader(dex路径, dex临时存储路径, native libraries 路径 , 父类classloader); //首先获得一个classloader。classloader相关知识这里不详细介绍了,以本篇主题为主吧。

.................. //其他的一些blah,blah.....

//当需要load 插件activity时,就进行如下操作。
Class localClass = dexClassLoader.loadClass(目的activity类名);//这里用dexClassLoader就可以load目的activity的class了,有了class,后面你就懂了,搬出反射大件吧。

Constructor localConstructor = localClass.getConstructor(new Class[] {}); //获得构造函数
Object instance = localConstructor.newInstance(new Object[] {});  //得到实例。好了,插件activity实例已经有了。恭喜。

2.用代理activity来为插件activity提供各种服务,比如说生命周期,获得资源,获得fragmentmanager等。起到一个proxy的作用,可以叫代理,也可以叫宿主。

宿主activity中:

//生命周期hooker
@Override
public void onXXX(){
    插件activity.onXXX();
} //代理activity的生命周期被触发时,直接触发插件activity的生命周期

//为插件activity提供插件的资源。
@Override
public AssetManager getAssets() {
    return 插件的assets;
}

@Override
public Resources getResources() {
    return 插件的resources;
}

@Override
public Theme getTheme() {
    return 插件的theme
}

插件Activity

@Override
public void onXXX(){
    插件activity.onXXX();
} //代理activity的生命周期被触发时,直接触发插件activity的生命周期

@Override
public void setContentView(View view) {
    ;//进行业务操作
}

@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return 代理activity.getSharedPreferences(name, mode);
        }
    } //利用代理activity来获得想要的sharedpreference,layoutinflater,systemservice等需要context才能获得的资源。

3.resources等资源,在load的时候可以获得,获得之后,塞给插件activity,让他在getResources()的时候,返回插件自带的resource就好了。

//获得插件activity对应的资源。
//获得插件activity的assetmanager.这里还是利用反射,把插件activity的assetmanagerload起来。
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, dex路径);

//获得resrouces
 Resources superRes = mContext.getResources();
 Resources resources = new Resources(插件的assetmanager, superRes.getDisplayMetrics(), superRes.getConfiguration());  


方案一 dynamic-load-apk 详细介绍

本节利用类图和时序图,让大家有一个较为详细的了解。
类图1: 主要介绍代理activity和插件activity的关系
Android 插件平台技术 基本介绍和dynamic-load-apk介绍_第1张图片
各个类和接口的作用是:
1.DLPluginInfo 实体类,主要存储插件activity的packageName,defaultActivityName,assets,resources等。
2.DLPlugin接口。插件activity的接口。主要包括两部分的能力:生命周期函数,attach方法。生命周期函数,是给插件activity一个壳子,让他可以像正常activity一样去处理生命周期。attach方法用于和宿主activity和DLPluginInfo产生关联关系,方便后续的调用。
3.DLAttachable。proxy activity的接口。定义的函数使得proxyActivity可以和DLPlugin,DLPluginInfo产生关联关系。
4.DLBasePluginActivity 插件activity的父类。
5.DLProxyActivity 为proxy activity。
6.DLProxyImpl proxyActivity在onCreate时会调用DLProxyImpl的initOnCreate方法,此方法会初始化一些主题相关的操作,

类图2:主要介绍调起的相关的类图
Android 插件平台技术 基本介绍和dynamic-load-apk介绍_第2张图片
1.Invoker 是入口的调起类。利用DLPluginManager来调起目的apk。
2.DLPluginManager 利用loadApk方法调起sd卡的apk,并用startPluginActivity方法来启动apk中的activity。
3.DLIntent 继承自Intent,包含了两个私有变量mPluginPackage和mPluginClass,目的是将这两个变量传递给DLProxyActivity。
(4.DLProxyActivity 上面已经介绍过了。)
时序图,主要介绍调起的流程
Android 插件平台技术 基本介绍和dynamic-load-apk介绍_第3张图片

1.利用PluginManager将sd卡上的apk load进内存。同时pluginmanager会保存插件apk的resource,assets等。
2.利用PlginMangager将插件apk 启动起来。
3.PlginMangager调用startPluginActivity来启动一个ProxyActivity,并将插件activity的包名和activity名传递给代理activity。
4.ProxyActivity在onCreate中利用DLProxyImpl进行一些初始化,主要是activity的theme设置,获得插件apk的asset和resource,并触发插件activity的onCreate方法。这样,插件activity的onCreate就被触发了。
5.插件activity的onCreate方法被触发了。后续声明周期,会由proxyActivity进行触发。这样,插件actiivty就运行起来了。

小结

1.此处只是基本介绍了dynamicloadapk的一些基本思路,具体内容还请有需要的朋友去看源码吧。
2.dynamicloadapk还可以代理service,这里并没有介绍。
3.后续会介绍其他的一些插件平台技术,希望对大家有帮助。下一篇为大家介绍directloadapk的技术。

Github 地址

  1. https://github.com/LiangChaoPossible/dynamic-load-apk.git

Reference

1.https://github.com/singwhatiwanna/dynamic-load-apk
2.http://get.ftqq.com/987.get
3.其他网络文章。此处有遗漏,请见谅。

你可能感兴趣的:(安卓插件平台)