SDK 开发使用 VirtualAPK 实现插件化

314 阅读2分钟
原文链接: www.ctolib.com

1. 背景

因为公司现在要在广告 SDK 开发中实现一部分代码的更新,或者是新增部分功能,因此需要从后台通过网络下载然后通过插件化的方式进行加载展示。本来想的是自己实现,但是遇到了一些问题,所以直接采用滴滴的开源框架 VirtualAPK 来实现。由于 VirtualAPK 是针对于 app 开发者的,所以我们在打包的时候需要把 SDK 稍微做一些改动。

2. 前期准备

滴滴开源框架 VirtualAPK 的 GitHub 地址为 github.com/didi/Virtua… ,通过 Wiki 的内容可以了解框架集成及使用。如果想了解原理则可以阅读源码进行了解。

3. 项目结构

SDK 开发使用 VirtualAPK 实现插件化

image

1. 宿主结构

内部有 HostMainActivity、HostMyApp 两个类

  1. HostMainActivity 用于插件加载和跳转插件中的页面
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
    String pluginPath = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/testpulgin.apk");
    File plugin = new File(pluginPath);
    try {
            PluginManager.getInstance(getApplicationContext()).loadPlugin(plugin);
        } catch (Exception e) {
            e.printStackTrace();
    }
} else {
    ActivityCompat.requestPermissions(this,
        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
        }
    TextView tv_host = findViewById(R.id.tv_host);
    tv_host.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.setClassName("keven.zcdog.pluginvirtual", "keven.zcdog.pluginvirtual.PluginMainActivity");
            startActivity(intent);
        }
});
  1. HostMyApp 用于主 APP 进行调用初始化 VirtualAPK
public class HostMyApp  {
    public static void init(Context context){
        PluginManager.getInstance(context).init();
    }
}

2. 插件结构

插件中就只有一个 Activity 和一个布局,供宿主调用。

4. 项目搭建

1. 项目配置

根据 GitHub 上的配置进行项目配置

  1. 在根目录的 build.gradle 文件中添加
classpath 'com.didi.virtualapk:gradle:0.9.8.6'

在根目录的 gradle.properties 文件中添加

android.useDexArchive=false
  1. 在宿主的 build.gradle 文件中添加
apply plugin: 'com.didi.virtualapk.host'
compile 'com.didi.virtualapk:core:0.9.8'
  1. 在插件项目的根目录 build.gradle 文件中添加(由于我这边插件和宿主在同一项目中,所以只需要配置一次即可)
classpath 'com.didi.virtualapk:gradle:0.9.8.6'
  1. 在插件的 build.gradle 文件中添加
apply plugin: 'com.didi.virtualapk.plugin'
virtualApk {
    packageId = 0x62  // 为了避免资源冲突.
    targetHost='D:/AndroidDemo/RetryVirtualApk/myaarhost' // 宿主项目位置,最好配置绝对路径,避免出错.
    applyHostMapping = true      // 默认为 true.
}

2. 生成插件包

先在 myaarhost 的 build.gradle 文件中进行修改

将
apply plugin: 'com.android.library'
替换为
apply plugin: 'com.android.application'

然后点击 Android Studio 右侧工具栏对宿主进行 build

SDK 开发使用 VirtualAPK 实现插件化

image

然后点击插件项目的 按钮生成插件 apk

SDK 开发使用 VirtualAPK 实现插件化

image

如果可以成功,可以在插件项目中找到(由于生成的是 release 包,所以需要配置下签名)

SDK 开发使用 VirtualAPK 实现插件化

image

如果过程中报错,可参考VirtualAPK 踩坑实录 ,我当时就是借鉴这篇文章的一些解决方法解决的。

5. 测试

  1. 将 myaarhost 改回 library,然后生成 aar
  2. 将产生的插件 apk 放入到手机根目录
  3. 新建项目,依赖 aar 包
  4. 在新建项目根目录配置
classpath 'com.didi.virtualapk:gradle:0.9.8.6'

在新建项目 app 下配置

compile 'com.didi.virtualapk:core:0.9.8'
  1. 新建类继承 Application ,调用 aar 中的方法初始化 VirtualAPK
public class MyApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        HostMyApp.init(base);
    }
}
  1. 启动 aar 中的 Activity
Intent intent = new Intent(MainActivity.this, HostMainActivity.class);
startActivity(intent);
  1. 实现效果

SDK 开发使用 VirtualAPK 实现插件化

image

6. 全部代码

本文所有代码见 GitHub 地址

github.com/keven0632/V…

查看原文: SDK 开发使用 VirtualAPK 实现插件化