Advertisement

Android插件学习汇总(持续更新)

阅读量:

Android插件学习

Android插件好处
  1. 实现热更新操作
  2. 业务热拔插
  3. 提高启动速度
基本实现

使用一个host APK作为empty shell application,在其动态加载功能下以实现插件包的加载,并进而支持动态版本更新。

开篇

作为一个新手阶段的学习者,在刚开始接触这一个块的内容学习时感到有些吃力。我希望可以通过循序渐进地深入学习这一过程,并逐步掌握动态加载的技术细节与实现原理,在最终的目标中构建一个较为完善的插件框架。

基础知识

DexClassLoader可以实现对于Dex、jar、Apk加载

1
入门篇
1. DL(Dynamic-load-apk)

该框架基于代理的方式构建插件框架。
由于作者已撰写相关文章,则可将其文章内容作为基础,并在此基础上进行补充。

代理原理:

第一步是定位插件包的位置;随后通过调用PackageManger.getPackageArchiveInfo()函数来得到相应的PackageInfo信息。

复制代码
    protected void launchTargetActivity() {
        PackageInfo packageInfo = getPackageManager().getPackageArchiveInfo(
                mDexPath, PackageManager.GET_ACTIVITIES);
        if ((packageInfo.activities != null)
                && (packageInfo.activities.length > 0)) {
            String activityName = packageInfo.activities[0].name;  // 主要是获取打开的Activity名称
            mClass = activityName;
            Log.d("TAG", mClass);
            launchTargetActivity(mClass);  // 作为参数传入
        }
    }

2、主要有三部
a. 通过反射调用获取到代理类

复制代码
    Class<?> localClass = dexClassLoader.loadClass(className);
    Constructor<?> localConstructor = localClass.getConstructor(new Class[] {});
    Object instance = localConstructor.newInstance(new Object[] {});

b. 传入当前Activity,代理类保存起来

复制代码
    Method setProxy = localClass.getMethod("setProxy",
    new Class[] { Activity.class });
    setProxy.setAccessible(true);
    setProxy.invoke(instance, new Object[] { this });  // 传入当前Activity

代理类中:

复制代码
    public void setProxy(Activity proxyActivity) {
        mProxyActivity = proxyActivity;
    }

c. 使用宿主APP的Activity对象来进行调用相关功能,即onCreate函数

复制代码
    Method onCreate = localClass.getDeclaredMethod("onCreate", new Class[] { Bundle.class });
    onCreate.setAccessible(true);
    Bundle bundle = new Bundle();
    bundle.putInt(FROM, FROM_EXTERNAL);
    onCreate.invoke(instance, new Object[] { bundle });

3、代理类BaseActivity:

复制代码
    @Override
    public void setContentView(View view) {
        if (mProxyActivity == this) {
            super.setContentView(view);
        } else {
            mProxyActivity.setContentView(view);  // 主要用传入的Activity类实现相关操作
        }
    }

注意:
为了访问相关路径下的插件包,需要相关的权限

复制代码
    <!-- 在SDCard中创建与删除文件权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!-- 往SDCard写入数据权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

结尾

对当前学习的一个总结

复制代码
    2017-04-19 16:47:10 更新的基础DL分析,下一步学习资源文件访问

全部评论 (0)

还没有任何评论哟~