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库,这样项目的功能才会更加完善,如下图就是最基本的第三方包的引用。


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

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

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


这是很正常的流程。

现在问题来了,在我们引用的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引入项目


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


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

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


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


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



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

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

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


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


三、引入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 {

    @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以下载的方式到本地加载

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



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

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值