Android DynamicLoadApk 开源插件开发项目代码剖析

目前的代码的目录结构是:

1、com.ryg.dynamicload.internal

2、com.ryg.dynamicload.service

3、com.ryg.dynamicload

4、com.ryg.dynamicload.utils


先看com.ryg.dynamicload.internal包下面的几个类:

1、DLAttachable

DL是DynamicLoad的缩写,Attachable是可连接的,整体的意思就是动态加载可以连接的。本质上这是一个接口,接口里面有一个方法,attach,其中的参数是插件开发所需要的代理DLPlugin,以及插件开发管理器DLPluginManager。

/**
     * when the proxy impl ( {@see DLProxyImpl#launchTargetActivity()} ) launch
     * the plugin activity , dl will call this method to attach the proxy activity
     * and pluginManager to the plugin activity. the proxy activity will load
     * the plugin's resource, so the proxy activity is a resource delegate for
     * plugin activity.
     * 
     * @param proxyActivity a instance of DLPlugin, {@see DLBasePluginActivity}
     *            and {@see DLBasePluginFragmentActivity}
     * @param pluginManager DLPluginManager instance, manager the plugins
     */

大致翻译一下文档上面的这段英文:

当代理实现类启动了插件的Activity,DL将会调用这个方法将代理Activity与插件管理器连接到插件Activity中,代理Activity将会加载插件的资源,所以代理Activity是插件内部的Activity的一个资源托管。


2、DLIntent

DLIntent是Intent的子类,它内部含有两个成员变量,分别是需要启动的插件的包名以及需要启动的插件的类名。


3、DLPluginManager

先分析其内部的成员变量,

先是三个整型常量:

START_RESULT_SUCCESS

START_RESULT_NO_PKG

START_RESULT_NO_CLASS

START_RESULT_TYPE_ERROR

分别表示 插件启动成功、没有找到指定的插件的包名、没有找到需要启动的插件的其中某一个class,还有就是指定的class的类型错误


还有一个变量是指定插件的so的目录

其中的方法无外乎 获取Dex,启动服务、停止服务、绑定服务、解绑定服务、启动Activity、加载指定class名的class、拷贝so文件等。


3、DLPluginPackage

字面意思看,指定的是一个插件的Apk。

看一下其中的注解:

 * A plugin apk. Activities in a same apk share a same AssetManager, Resources
 * and DexClassLoader.

一个插件的Apk,在一个相同的Apk中的一系列的Activities共享一个相同的AssetManager、Resources以及DexClassLoader。

成员变量如下:



1、插件的完整包名

2、默认的Activity的名称

3、Dex类加载器

4、AssetManager对象

5、资源Resources对象

5、包的相关描述对象  PackageInfo对象


4、DLProxyImpl

字面意思是插件代理的实现。

注解如下:

 * This is a plugin activity proxy, the proxy will create the plugin activity
 * with reflect, and then call the plugin activity's attach、onCreate method, at
 * this time, the plugin activity is running.

这是一个插件Activity的代理,代理将会利用反射创建插件Activity,同时调用插件Activity的attach以及onCreate的方法,此时插件Activity就处于运行的状态了。

成员变量如下:


 private String mClass;
 private String mPackageName;


 private DLPluginPackage mPluginPackage;
 private DLPluginManager mPluginManager;


 private AssetManager mAssetManager;
 private Resources mResources;
 private Theme mTheme;


 private ActivityInfo mActivityInfo;
 private Activity mProxyActivity;
 protected DLPlugin mPluginActivity;
 public ClassLoader mPluginClassLoader;

1、当前的插件Activity的类名

2、当前插件Activity的包名

3、标识当前的插件Apk的对象

4、插件管理器

5、Asset管理器

6、资源管理器

7、主题对象

8、描述当前的插件Activity的相关的信息的对象

9、代理Activity的对象

10、插件的接口

11、类加载器


5、DLServiceAttachable

这个类与DLAttachable的功能是类似的,只不过是一个是针对Activity,一个是针对service。


6、DLServiceProxyImpl

在构造函数中,其中需要的参数是代理服务对象。

初始化init的函数是一个intent的对象。

内部的流程简介如下:

1、利用类加载器加载指定的插件内部的服务的名称,实际上是利用反射创建对象

2、将插件内部的Service对象绑定到代理Service对象上面

3、直接调用插件Service的onCreate的方法


接下来再看com.ryg.dynamicload包下面的几个类:

1、DLBasePluginActivity

其中成员变量如下:

 /**
     * 代理activity,可以当作Context来使用,会根据需要来决定是否指向this
     */
    protected Activity mProxyActivity;


    /**
     * 等同于mProxyActivity,可以当作Context来使用,会根据需要来决定是否指向this<br/>
     * 可以当作this来使用
     */
    protected Activity that;
    protected DLPluginManager mPluginManager;
    protected DLPluginPackage mPluginPackage;

1、代理Activity是真正运行中的Activity

2、插件管理器

3、插件的包名

4、默认是来自于插件的内部


下面对这个类中的主要方法做下面的介绍:

1、代理Activity的赋值

2、指向插件Apk对象的本身的赋值

3、同时发现,类似onCreate、setContentView等与Activity相关的方法,判断是内部启动还是外部启动,如果是内部启动,完全可以不需要代理Activity的处理,如果是外部

启动,凡是与Activity相关的,均需要代理Activity处理

4、有一点要注意,凡是调用了onAttach,均是属于外部的启动


2、DLBasePluginFragmentActivity

这个类与DLBasePluginActivity同理,不再进行赘述。


3、DLPlugin

这是一个插件开发的接口,接口中的方法如下:

    public void onCreate(Bundle savedInstanceState);
    public void onStart();
    public void onRestart();
    public void onActivityResult(int requestCode, int resultCode, Intent data);
    public void onResume();
    public void onPause();
    public void onStop();
    public void onDestroy();
    public void attach(Activity proxyActivity, DLPluginPackage pluginPackage);
    public void onSaveInstanceState(Bundle outState);
    public void onNewIntent(Intent intent);
    public void onRestoreInstanceState(Bundle savedInstanceState);
    public boolean onTouchEvent(MotionEvent event);
    public boolean onKeyUp(int keyCode, KeyEvent event);
    public void onWindowAttributesChanged(LayoutParams params);
    public void onWindowFocusChanged(boolean hasFocus);
    public void onBackPressed();
    public boolean onCreateOptionsMenu(Menu menu);
    public boolean onOptionsItemSelected(MenuItem item);

基本上囊括了Activity中的所有系统的方法。


4、DLProxyActivity

插件Activity的代理类。

其中的成员变量包括:1、DLPlugin  2、DLProxyImpl  一个是指向插件对象   一个是指向代理的实现的对象

既然是插件的代理类,很显然,这里面的实现方法我们都能够猜测的到,凡是与Activity相关的方法,一方面会调用插件自身Activity的方法,另一个方面,在同样的方法中,会调用代理Activity中的方法。


5、DLProxyFragmentActivity

与DLProxyActivity类似,不再赘述。


6、DLProxyService

这个是Service代理服务。


从上面的变量看,主要包括下面的三点:

1、Service的代理实现

2、插件内部本身的Service

3、插件的管理器


在功能的实现上,其实与Activity的代理实现是一样的,凡是关键性的内部方法均是代理类与插件类同时调用,其余不再赘述。


7、DLServicePlugin

囊括了Service的关键性的方法的接口,不再赘述。


最后再来看com.ryg.dynamicload.util包下面的几个类:

1、DLConfigs

存储与获取so的修改时间


2、DLConstants

在这个常量类中,主要是配置下面几大类常量

1、内部启动还是外部启动

2、Dex路径 以及相关的包名  存储的Tag

3、Activity的相关的类型

4、CPU的相关的体系结构


3、DLUtils

这个一个工具类

包含下面一组功能

1、获取在Sdk目录下指定插件Apk文件的包名 getPackageInfo

2、获取在Sdk目录下指定插件Apk文件的应用图标 getAppIcon

3、获取在Sdk目录下指定插件Apk文件的应用名称 getAppLabel

4、还有就是利用反射机制获取指定的插件Activity中的类型


4、SoLibManager

1、获取CPU相关的信息  2、在线程中将插件的so文件拷贝到 当前工程目录的so文件的目录文件夹中(根据当前的cpu体系结构,拷贝合适的so文件)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值