android 插件化动态加载apk包(插件apk不需要安装)

时间:2024-03-20 15:09:13

android 插件化动态加载apk包(插件apk不需要安装)

本案例是基于大神的基础实现的,大神项目源码:https://github.com/houkx/android-pluginmgr/

本案例插件项目源码:https://github.com/Y-Duan/android_plugin_make

本案例宿主项目源码:https://github.com/Y-Duan/PluginApp

先来说一下背景,正常情况下新建一个项目,根据需求的不同会引入各种第三方jar包和so库,这样项目的功能才会更加完善,如下图就是最基本的第三方包的引用。

android 插件化动态加载apk包(插件apk不需要安装)

1:之前demo中生成的so库文件,里面的方法返回一个字符串。生成so文件

2:之前demo生成的jar包,里面只有一个类Testjni,调用so里面的getString方法,返回一个字符串。生成jar包

3:调用使用。弹出toast(先不要在意字符串内容)调用jar包和so文件

android 插件化动态加载apk包(插件apk不需要安装)

这是很正常的流程。

现在问题来了,在我们引用的jar包和so库慢慢增多的情况下,apk的体积也在增大,虽然如今手机的存储空间也在迅速增大,但是android用户还是喜欢小一点的体积包的。像一个app 100M的话,估计下载的用户会很少。所以就需要将功能模块化,真正的app就是一个框架一个,用户需要什么功能再自行添加就可以,不至于用户第一眼看到100M的app受到惊吓导致用户流失。

实现需求背景来了,看上面的图,现在假设,1:jar包和2:三个so库文件体积很大,就夸张假设100M吧,那整个app大小是非常大的。所以现在我们需要将这jar包和so库文件放到插件apk中,用户需要的时候或宿主app启动的时候再下载下来。这样原来的宿主app就非常小了。


主要是通过多态来实现的

第一步:先制作插件apk

前提准备:需要两个东西,真实项目中需要引入的(体积很大的)第三方jar包和so库文件,这里我使用自己创建的jar包和so文件来模拟

一、我们先来创建一个插件项目,把之前生成的jar包和so文件放进来,并将lib.jar引入项目

android 插件化动态加载apk包(插件apk不需要安装)

二、在这个项目中创建一个library类型的module,名为pluginlib,里面只有一个接口

android 插件化动态加载apk包(插件apk不需要安装)

三、我们需要在插件apk中实现这个接口,在插件apk中引入pluginlib这个module,创建一个类实现接口,调用真正需要使用so的逻辑

android 插件化动态加载apk包(插件apk不需要安装)

四、将pluginlib这个module打成jar引入到插件apk中,因为还需要宿主apk使用。这个jar包就是插件和宿主之间的桥梁。至此插件项目就成这样了,pluginlib只需要jar包,module不需要了。

android 插件化动态加载apk包(插件apk不需要安装)

五、最后一步,也是重要的一步,引入这个只有一个接口的pluginlib.jar包时,一定要设置成Provided,(Compile是将jar打进apk文件中的,更多设置可以自行搜索,这里就不多说了)这样,把插件打成apk时,里面就不会包含这个jar文件,之后在宿主apk中引入这个jar就不会出现重复引入错误。

android 插件化动态加载apk包(插件apk不需要安装)

现在把插件打成apk文件,要使用release版本的,改个名字,一个插件就制作完成了。

android 插件化动态加载apk包(插件apk不需要安装)

android 插件化动态加载apk包(插件apk不需要安装)

为了方便测试和调试,提供了插件的源码下载,apk包在apk文件夹中

第二步 创建宿主程序来使用插件apk

一、新建一个新的项目,将libplugin.jar copy到libs目录下(要自己新建,不要使用系统的libs)

android 插件化动态加载apk包(插件apk不需要安装)

二、新建一个library类型的module,导入第三方库,这是github上大神写的,本案例是基于此实现的。

android 插件化动态加载apk包(插件apk不需要安装)

三、引入jar包和module到宿主项目中,还有一步重要的,添加文件读写权限

<!--在SDCard中创建与删除文件权限-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!--往SDCard写入数据权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--从SDCard读取数据权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
activity中调用
public class MainActivity extends AppCompatActivity {
<span style="color:#808000;">@Override

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化插件管理对象
PluginResource pluginResource = PluginResource.getInstance();
if(!pluginResource.initPluginResource(this))return;
//获取接口对象
IShowString iShowString = pluginResource.getPluginString();
if(iShowString!=null){
String toast = iShowString.showString(“1”,“2”);
Toast.makeText(this,toast,Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,“对象为空”,Toast.LENGTH_SHORT).show();
}
}
}

将插件apk改名为plugin.apk,并放到手机存储的plugin文件夹中,没有就创建一个,路径和插件名称在代码中是可以修改的,真实项目中可以将插件apk以下载的方式到本地加载

android 插件化动态加载apk包(插件apk不需要安装)

如果出现下图错误的请看另一篇文章:IllegalAccessError异常错误

android 插件化动态加载apk包(插件apk不需要安装)

android 插件化动态加载apk包(插件apk不需要安装)

插件项目就此结束,喜欢的同学可以看看源码研究一下,自己修改修改。


转载原文 https://blog.csdn.net/u012898654/article/details/80341403