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

Posted zhangjiaofa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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文件)



以上是关于Android DynamicLoadApk 开源插件开发项目代码剖析的主要内容,如果未能解决你的问题,请参考以下文章

罗列几个Android插件化开发框架

Android逆向系列文章— Android基础逆向

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

android 21 是啥版本

Android逆向-Android基础逆向(2-2)