滴滴插件化框架 VirtualAPK 接入踩坑實踐

  • 2019.9.30
  • VirtualAPK
  • 接入指南
    • 一 預注意事項
      • 1. gradle-wrapper.properties
      • 2. 根 build.gradle 配置
      • 3. 注意混淆
      • 4. 依賴庫
    • 二 宿主程序
      • 1. 應用級 build.gradle 配置
      • 2. 初始化
      • 3. 假設已有插件包
        • (1)安裝
        • (2)檢查插件是否安裝
        • (3)啟動
        • (4)刪除插件
    • 三 插件程序
      • 1. 應用級 build.gradle 配置
      • 2. 生成插件包
      • 3. 問題
        • (1) 使用 FragmentActivity
        • (2) Theme.AppCompat.Light.NoActionBar 主題無法去除 ActionBar
        • (3) IncompatibleClassChangeError
        • (4) 插件使用 material 控件會報錯
        • (5) CardView 背景會變黑
        • (6) 約束布局在插件中無效
        • (7) 其他

2019.9.30

以下內容時當前時間2019.9.30版本下,跑通了 VirtualAPK 的踩坑接入總結裁奇。

VirtualAPK

https://github.com/didi/VirtualAPK

要是在 RePlugin 和 VirtualAPK 里選對話音五,我更偏向 RePlugin, 因為它至少可用 AppCompatActivity羔沙, VirtualAPK 在 2019.9.30 當前版本的插件里面只能用 Activity躺涝,而且插件不支持多module, 倒是 入侵性極低 這個很不錯。

但是扼雏,至少可以讓項目跑起來上線坚嗜,在當前已經接入百萬級APP里看,還算穩(wěn)定呢蛤。

接入指南

官網(wǎng) Wiki 也說的很詳細, 建議使用 Androidx惶傻。

一 預注意事項

宿主和插件保持一致性,才會讓坑更少點其障。

1. gradle-wrapper.properties

image.png

目前最好使用 4.6:

#Fri Mar 01 16:49:19 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

2. 根 build.gradle 配置

classpath 'com.android.tools.build:gradle:3.2.0'
classpath 'com.didi.virtualapk:gradle:0.9.8.6.2-dev'

3. 注意混淆

混淆文件盡量保持一致银室。如果報錯提示沒有找到某個文件,那么就是這個文件需要被keep励翼。

記住 keep 你的啟動頁蜈敢,別讓它被混淆了。

virtualapk 混淆:

-keep class com.didi.virtualapk.internal.VAInstrumentation { *; }
-keep class com.didi.virtualapk.internal.PluginContentResolver { *; }
-dontwarn com.didi.virtualapk.**
-dontwarn android.content.pm.**

如果插件使用 Retrofit+Rxjava+OkHttp:

#retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keep class io.reactivex.**
-keep class io.reactivex.** { *; }

#okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
-keep interface okhttp3.**{*;}
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *;}
-dontwarn okio.**

# rxjava
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
 long producerIndex;
 long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
 rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
 rx.internal.util.atomic.LinkedQueueNode consumerNode;
}

4. 依賴庫

在當前測試情況下汽抚,只要把插件的依賴庫完整的拷貝一份到宿主里面抓狭,就可以不用針對不同宿主重新編譯插件包。
插件所用依賴庫的版本必須和宿主一致造烁。

二 宿主程序

宿主的資源id最好有自己的命名前綴否过,如果想坑少點午笛。

1. 應用級 build.gradle 配置

應用插件:

apply plugin: 'com.android.application'
apply plugin: 'com.didi.virtualapk.host'

可以使用 Java 8:

android {
 ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

添加 virtualapk 依賴:

implementation ('com.didi.virtualapk:core:0.9.9.1-dev') {
        exclude group: 'com.android.support'
    }

2. 初始化

在 Application 進行初始化

   @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        PluginManager.getInstance(base).init();
    }

3. 假設已有插件包

插件包后綴必須 .apk

(1)安裝
PluginManager.getInstance(PCache.getContext()).loadPlugin(file);

需要記錄插件啟動頁相對路徑比如: com.afra55.greate.MainActivity

安裝代碼執(zhí)行后苗桂,插件包不要刪除药磺,目前的情況是,每次進入插件都 安裝一次才不會出問題煤伟。

(2)檢查插件是否安裝

自己進行安裝判斷癌佩。

(3)啟動
  Intent intent = new Intent();
            intent.setClassName(packageName, "com.afra55.greate.MainActivity");
            context.startActivity(intent);
(4)刪除插件

無。

三 插件程序

注意便锨,如果有多個 module围辙,最好把多個module 的代碼都放到一個module下,不能直接去依賴module 會出錯放案。 或者把module庫代碼放到 maven 倉庫去依賴姚建。

插件不支持分包,代碼越少越好卿叽,重的依賴庫就放到宿主桥胞,通過反射調用恳守。

插件不能配置 Java8, 謹記考婴。

1. 應用級 build.gradle 配置

在最底下配置:

apply plugin: 'com.didi.virtualapk.plugin'

virtualApk {
    packageId = 0x6f // 插件的唯一標志,不用插件要有不同的 packageId.
    targetHost = '/Users/afra55/Program/Android/TestMaster/app' // TODO(根據(jù)不同的項目催烘,修改成應用級module的全路徑)
    applyHostMapping = true //optional, default value: true.
    forceUseHostDependences = true // 強制使用宿主工程的依賴
}

targetHost 需要根據(jù)不同的項目沥阱,修改成應用級module的全路徑。
上面也提到了伊群,拷貝一份插件的全部依賴到宿主考杉,插件包就可以復用。
這樣就配置完成了舰始。

2. 生成插件包

使用Terminal到應用級目錄下執(zhí)行命令:

 ../gradlew clean assemblePlugin

這樣就打包出來了崇棠。
可以修改打包路徑 (適用 gradle-3.2.0):

   release {
            signingConfig signingConfigs.release
            debuggable false
            zipAlignEnabled true
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            applicationVariants.all { variant ->
                variant.outputs.all { output ->
                    def outputFile = output.outputFile
                    if (outputFile != null &&
                            outputFile.name.endsWith('release.apk')) {
                        variant.getPackageApplication().outputDirectory = new File("${getApkSavedPath()}")
                        def fileName =
                                "afra55.apk"
                        output.outputFileName = fileName
                    }
                }
            }
        }

3. 問題

(1) 使用 FragmentActivity

不能使用 AppCompatActivity, 會報錯

(2) Theme.AppCompat.Light.NoActionBar 主題無法去除 ActionBar

在代碼里實現(xiàn)你的去ActionBar效果丸卷,在主題里無效:

  try {
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            ActionBar actionBar = getActionBar();
            if (actionBar != null) {
                actionBar.hide();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
(3) IncompatibleClassChangeError

凡是出現(xiàn)這個問題枕稀,就是插件和宿主的相同依賴度的版本不一致造成的。

(4) 插件使用 material 控件會報錯

去除 material 控件谜嫉,自己寫一個吧萎坷。

(5) CardView 背景會變黑

那就別用了,自己寫個沐兰。

(6) 約束布局在插件中無效

換掉哆档。

(7) 其他

參考官網(wǎng)的常見問答:https://github.com/didi/VirtualAPK/wiki/常見問題解答

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市住闯,隨后出現(xiàn)的幾起案子瓜浸,更是在濱河造成了極大的恐慌澳淑,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件插佛,死亡現(xiàn)場離奇詭異偶惠,居然都是意外死亡,警方通過查閱死者的電腦和手機朗涩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門忽孽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谢床,你說我怎么就攤上這事兄一。” “怎么了识腿?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵出革,是天一觀的道長。 經常有香客問我渡讼,道長骂束,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任成箫,我火速辦了婚禮展箱,結果婚禮上,老公的妹妹穿的比我還像新娘蹬昌。我一直安慰自己混驰,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布皂贩。 她就那樣靜靜地躺著栖榨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪明刷。 梳的紋絲不亂的頭發(fā)上婴栽,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音辈末,去河邊找鬼愚争。 笑死,一個胖子當著我的面吹牛本冲,可吹牛的內容都是我干的准脂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼檬洞,長吁一口氣:“原來是場噩夢啊……” “哼狸膏!你這毒婦竟也來了?” 一聲冷哼從身側響起添怔,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤湾戳,失蹤者是張志新(化名)和其女友劉穎贤旷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砾脑,經...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡幼驶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了韧衣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盅藻。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖畅铭,靈堂內的尸體忽然破棺而出氏淑,到底是詐尸還是另有隱情,我是刑警寧澤硕噩,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布假残,位于F島的核電站,受9級特大地震影響炉擅,放射性物質發(fā)生泄漏辉懒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一谍失、第九天 我趴在偏房一處隱蔽的房頂上張望眶俩。 院中可真熱鬧,春花似錦袱贮、人聲如沸仿便。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至荒勇,卻和暖如春柒莉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沽翔。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工兢孝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仅偎。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓跨蟹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親橘沥。 傳聞我的和親對象是個殘疾皇子窗轩,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內容

  • 轉載請注明出處:http://www.reibang.com/p/b2d2ed1088bb[https://ww...
    容華謝后閱讀 3,768評論 1 22
  • 項目VirtualApkProgram中采用要實行插件化首先考慮的是采用哪種方式,怎么實現(xiàn)等等座咆,經過一番調研發(fā)現(xiàn)目...
    xuancaocom閱讀 1,003評論 0 1
  • 本文思路: 1.VirtualAPK 介紹(如果只是想先簡單接入痢艺,跳過這部分) 2.VirtualAPK 基本使用...
    gogoingmonkey閱讀 4,905評論 0 6
  • 觀《義旱淌妫》題作 烽火遍青城色建, 民殤。 問歲月期長舌缤, 何安箕戳, 興,百姓苦国撵, 亡漂羊,百姓苦。 連月下卸留,塞上里走越, 狼煙四起...
    善卿上水閱讀 420評論 2 11
  • 事有始時,必有始終耻瑟,關于城墻旨指,打造自我 沒見成效,未有績果喳整,沒權享受谆构,無利擁有 寫下此文,意在提醒框都,改變局面搬素,全在...
    舒童GoDoneNow閱讀 152評論 0 0