滴滴開源Android插件方案:VirtualAPKandroid
(1)在整個工程的build.gradle中添加依賴git
dependencies { classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.didi.virtualapk:gradle:0.9.8.4' // VirtualApk // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }
(2)在app模塊(宿主App模塊名,可更名)build.gradle添加插件引用github
apply plugin: 'com.didi.virtualapk.host' // VirtualApk build.gradle文件頂部添加
(3)在app模塊build.gradle中添加依賴app
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' compile 'com.didi.virtualapk:core:0.9.6' // VirtualApk }
(4)在Application的attachBaseContext中添加PluginManager初始化代碼ide
import com.didi.virtualapk.PluginManager; public class TestApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); long start = System.currentTimeMillis(); PluginManager.getInstance(base).init(); // 主要是這句 Log.d("KLH", "use time:" + (System.currentTimeMillis() - start)); } }
(5)在MainActivity的OnCreate中自動加載插件(這一步的時機可選,也能夠是後續再加載),請注意這裏加載插件的路徑和apk名稱,要約定好。測試
private void loadPlugin() { PluginManager pm = PluginManager.getInstance(this); File apk = new File(Environment.getExternalStorageDirectory(), "test_plugin.apk"); if (apk.exists()) { try { pm.loadPlugin(apk); showToast("插件加載成功!!!"); } catch (Exception e) { e.printStackTrace(); showToast("插件加載異常了。。。"); } } }
(6)啓動插件Apk(這裏以啓動插件中的一個Activity爲例)gradle
Intent intent = new Intent(); intent.setClassName("com.klh.testplugin", "com.klh.testplugin.MainActivity"); startActivity(intent);
插件工程是一個獨立的App工程,只不過添加了VirtualAPK相關依賴,而且在編譯時須要關聯宿主工程目錄(爲了作一些信息同步與共享庫刪減)ui
(1)在整個工程的build.gradle中添加依賴this
dependencies { classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.didi.virtualapk:gradle:0.9.8.4' // VirtualApk // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }
(2)在app模塊的build.gradle中添加依賴spa
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' compile 'com.didi.virtualapk:core:0.9.6' // VirtualApk }
(3)在app模塊的build.gradle文件末尾中添加插件配置
// VirtualApk apply plugin: 'com.didi.virtualapk.plugin' virtualApk { // 要指定一個不重複的ID來區分插件資源,有效值範圍:[0x02, 0x7E] packageId = 0x6a // the package id of Resources. // 宿主App的Application模塊(絕對/相對)路徑,插件的構建須要依賴此路徑 targetHost = '../testAndroid/app' // the path of application module in host project. // 若是插件有引用宿主的類,那麼此選項能夠確保插件與宿主保持混淆一致 applyHostMapping = true //optional, default value: true. }
(4)編譯方法:gradlew clean assemblePlugin
(1)安裝宿主App
(2)將編譯好的插件更名與宿主約定一致,推送到指定目錄。例如本文的約定路徑是:/sdcard/test_plugin.apk
E:\VirtualShare\gitLab\research\05.VirtualApk\VATestPlugin>adb push app\build\outputs\apk\release\app-release-unsigned.apk /sdcard/test_plugin.apk
app\build\outputs\apk\release\app-release-unsigned.apk: 1 file pushed. 0.9 MB/s (27437 bytes in 0.030s)
插件不能直接訪問宿主App的接口,可採用與宿主App集成相同的aar包來實現數據交互。