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

这篇博客探讨了Android插件化的益处,如热更新和业务模块的灵活替换,以及如何通过一个空壳宿主APK实现动态加载功能。作者详细介绍了使用DexClassLoader加载Dex、jar和Apk的基础知识,并且讲解了DL(Dynamic-load-apk)框架的代理原理,包括获取插件位置、反射创建代理类和在宿主Activity中调用相关功能。博客以作者的学习过程为线索,旨在构建一个完整的插件框架。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android插件学习

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

使用一个宿主APK,即空壳程序,通过动态加载功能跟实现插件包调用,从而实现动态更新的功能。

开篇

对于这一个块的内容学习,我也是刚刚接触,希望从我一步一步学习下去,由浅入深,更好的理解这个动态加载过程,最终目标能够实现一个相对比较完备的插件框架。
å

基础知识

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

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

该框架使用代理的方式实现插件框架
由于作者写过相关的文章,这边引用其文章内容作为基础,我对其进行补充。
Android apk动态加载机制的研究
首先根据上面的文章进行第一次的实践,在实践过程中进行理解和分析。
在上述文章中主要讲的是如何实现代理,如何对Activity类进行改造。

代理原理:

1、首先获取到插件包位置,然后调用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分析,下一步学习资源文件访问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值