Android全面插件化方案-RePlugin踩坑

1.什么是RePlugin醉锅?

在Android開發(fā)領(lǐng)域勤庐,有關(guān)插件化的討論一直熱度不減二鳄。目前市面上的插件化方案雖然很多曙搬,但多數(shù)只能實現(xiàn)某些功能的插件化摔吏,距離開發(fā)者的預期尚有相當差距。對此纵装,在近期GMTC全球移動技術(shù)大會上征讲,360手機衛(wèi)士主程序架構(gòu)負責人張炅軒宣布,360的插件化框架RePlugin已經(jīng)可以實現(xiàn)“全面插件化”橡娄,同時具有出色的穩(wěn)定性和靈活性诗箍,可適用于各種類型的應用上。
“RePlugin預計7月份開源挽唉,這將是我們獻給安卓世界最好的禮物滤祖。”360如是說橱夭。

2.RePlugin有什么用氨距?

RePlugin是一套完整的、穩(wěn)定的棘劣、適合全面使用的俏让,占坑類插件化方案,由360手機衛(wèi)士的RePlugin Team研發(fā)茬暇,也是業(yè)內(nèi)首個提出”全面插件化“(全面特性首昔、全面兼容、全面使用)的方案糙俗。

3.RePlugin官方介紹

其主要優(yōu)勢有:

  • 極其靈活:主程序無需升級(無需在Manifest中預埋組件)勒奇,即可支持新增的四大組件,甚至全新的插件
  • 非常穩(wěn)定:Hook點僅有一處(ClassLoader)巧骚,無任何Binder Hook赊颠!如此可做到其崩潰率僅為“萬分之一”,并完美兼容市面上近乎所有的Android ROM
  • 特性豐富:支持近乎所有在“單品”開發(fā)時的特性劈彪。包括靜態(tài)Receiver竣蹦、Task-Affinity坑位、自定義Theme沧奴、進程坑位痘括、AppCompat、DataBinding等
  • 易于集成:無論插件還是主程序,只需“數(shù)行”就能完成接入
  • 管理成熟:擁有成熟穩(wěn)定的“插件管理方案”纲菌,支持插件安裝挠日、升級、卸載翰舌、版本管理嚣潜,甚至包括進程通訊、協(xié)議版本椅贱、安全校驗等
  • 數(shù)億支撐:有360手機衛(wèi)士龐大的數(shù)億用戶做支撐郑原,三年多的殘酷驗證,確保App用到的方案是最穩(wěn)定夜涕、最適合使用的

截止2017年6月底犯犁,RePlugin的:

特性 描述
插件數(shù) 103(核心57個)
插件占應用比 高達83%
年發(fā)版次數(shù) 高達596次(工作日均2次)
崩潰率 萬分之一(0.01%),極低
時間 2014年應用女器,3年驗證

目前360公司幾乎所有的億級用戶量的APP酸役,以及多款主流第三方APP,都采用了RePlugin方案驾胆。

有關(guān)RePlugin的詳細介紹涣澡,請點擊這里閱讀《RePlugin 官方 WiKi》

還支持以下特性

特性 描述
組件 四大組件(含靜態(tài)Receiver)
升級無需改主程序Manifest 完美支持
Android特性 支持近乎所有(包括SO庫等)
TaskAffinity & 多進程 支持(坑位方案)**
插件類型 支持自帶插件(自識別)丧诺、外置插件**
插件間耦合 支持Binder入桂、Class Loader、資源等
進程間通訊 支持同步驳阎、異步抗愁、Binder、廣播等
自定義Theme & AppComat 支持
DataBinding 支持
安全校驗 支持
資源方案 獨立資源 + Context傳遞(相對穩(wěn)定)
Android 版本 API Level 9+ (2.3及以上)

愿景

讓插件化能飛入尋常應用家呵晚,做到穩(wěn)定蜘腌、靈活、自由饵隙,大小項目兼用撮珠。

RePlugin 架構(gòu)圖

RePlugin Framework
RePlugin Framework

4.SO?怎么用?

ok金矛,看完了官方介紹給我們畫的大餅芯急,現(xiàn)在看看怎么實現(xiàn)它,是的驶俊,坑來了娶耍。。
主程序的配置废睦,這里就不多說了伺绽。养泡。將RePlugin接入到您的主程序嗜湃,官方文檔描述的很清楚奈应,也沒有什么奇奇怪怪的錯誤。
主要來說說如何開發(fā)新的 RePlugin 插件购披,從RePlugin的Wiki我們可以看到杖挣,好簡單呀,就三步嘛刚陡,來吧惩妇。
然后我們碰到了.........

問題一:Gradle配置出錯

gradle配置出錯.png

EXCUSE ME?那里有問題筐乳?再看看文檔歌殃,沒啥特別的描述呀。
然后蝙云,我在Issues里找到了官方項目組說的這一句:“這個要自動讀取前面build.gradle的配置內(nèi)容氓皱,如果放在前面,會讀為空勃刨。我們內(nèi)部討論過這個問題波材,如果要想自由放置就得傳參配置。當時考慮到盡量減少傳參配置就約定俗成讓放在文件末尾身隐。你可以看demo1廷区。”
好吧贾铝,既然如此能不能提一句只能放在文件末尾跋肚帷!
你是360垢揩,你老大大脉,我改!

gradle配置出錯.png

水孩?镰矿?按你說的還不行?俘种?
然后秤标,我在Issues里看到了吃瓜群眾說的這一句:“你試試把apply plugin: 'replugin-plugin-gradle'放在<apply plugin: 'com.android.application'之前就好了,我的就是這樣好使的宙刘,你試試?”
抱著試一試的心態(tài)苍姜,然后我發(fā)現(xiàn)...成功了?悬包?說好的讀取配置內(nèi)容呢衙猪?說好的會讀為空呢?

OK,按照官方文檔垫释,各項都配置完成丝格,我們繼續(xù)進行。棵譬。
插件界面很簡單:


image.png

插件單獨運行一下显蝌,ok,沒問題订咸。
好的曼尊,接下來走一下內(nèi)置插件的流程,將插件項目build一個apk出來脏嚷,后綴改成jar骆撇,導入主程序assets的plugins內(nèi),
主程序界面也很簡單父叙,就一個HelloRePlugin的TextView艾船,給TextView設(shè)置一個點擊事件

tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RePlugin.startActivity(MainActivity.this, RePlugin.createIntent("aap2", "com.zzcn77.replugindemo2.MainActivity"));
            }
        });

然后我們碰到了.........

問題二:主題出錯

點擊HelloRePlugin,程序崩潰高每。

主題出錯

主題錯了屿岂?繼承的是Activity啊,有主題啊鲸匿,單獨運行沒有錯啊爷怀。。
自此带欢,我開始多番嘗試之路运授,改了n個主題發(fā)現(xiàn)沒有用,氣的我乔煞,直接把apply plugin: 'replugin-plugin-gradle'
我把這句去掉了吁朦,運行。渡贾。程序調(diào)起成功了逗宜。。空骚。我的天哪
詭異的一幕出現(xiàn)了纺讲,吊起的插件Acitivity顯示界面:
主題錯誤

?囤屹?熬甚?這個界面哪來的?肋坚,這不是我的插件界面啊乡括。肃廓。
奇怪的是,插件的activity的onCreate也走了诲泌。那我的界面去哪了盲赊?
是不是因為我刪去了apply plugin: 'replugin-plugin-gradle',所以出現(xiàn)問題了档礁?,還是加上吧吝沫,再看看主題出錯有沒有其他解決方法呻澜。------加上,buildApk惨险,導入主程序羹幸,運行主程序,點擊HelloRePlugin辫愉,調(diào)起栅受,成功了?恭朗!屏镊,唉?你不是主題有問題的嗎痰腮?你不是主題有問題的嗎而芥?你不是主題有問題的嗎?好吧膀值,棍丐,雖然調(diào)起成功,可是還沒完沧踏,打開的activity界面依然如上歌逢。

網(wǎng)絡(luò)圖片

然后我們發(fā)現(xiàn)了.........

問題三: Didn't find class "com.qihoo360.plugin.app2.Entry"

 Didn't find class "com.qihoo360.plugin.app2.Entry" on path: DexPathList[[zip file "/data/user/0/com.replugindemo/app_plugins_v3/app2-10-10-101.jar"],nativeLibraryDirectories=[/data/user/0/com.replugindemo/app_plugins_v3_libs/app2-10-10-101, /vendor/lib, /system/lib]]
 java.lang.ClassNotFoundException: Didn't find class "com.qihoo360.plugin.app2.Entry" on path: DexPathList[[zip file "/data/user/0/com.replugindemo/app_plugins_v3/app2-10-10-101.jar"],nativeLibraryDirectories=[/data/user/0/com.replugindemo/app_plugins_v3_libs/app2-10-10-101, /vendor/lib, /system/lib]]
                 at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                 at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                 at com.qihoo360.replugin.PluginDexClassLoader.loadClass(PluginDexClassLoader.java:76)
                 at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                 at com.qihoo360.loader2.Loader.loadEntryMethod2(Loader.java:419)
                 at com.qihoo360.loader2.Plugin.loadEntryLocked(Plugin.java:857)
                 at com.qihoo360.loader2.Plugin.doLoad(Plugin.java:822)
                 at com.qihoo360.loader2.Plugin.loadLocked(Plugin.java:621)
                 at com.qihoo360.loader2.Plugin.load(Plugin.java:432)
                 at com.qihoo360.loader2.PmBase.loadPlugin(PmBase.java:1033)
                 at com.qihoo360.loader2.PmBase.loadAppPlugin(PmBase.java:1018)
                 at com.qihoo360.loader2.PmLocalImpl.getActivityInfo(PmLocalImpl.java:443)
                 at com.qihoo360.loader2.PmLocalImpl.loadPluginActivity(PmLocalImpl.java:319)
                 at com.qihoo360.loader2.PmInternalImpl.startActivity(PmInternalImpl.java:230)
                 at com.qihoo360.loader2.PmLocalImpl.startActivity(PmLocalImpl.java:307)
                 at com.qihoo360.i.Factory.startActivityWithNoInjectCN(Factory.java:324)
                 at com.qihoo360.replugin.RePlugin.startActivity(RePlugin.java:236)
                 at com.zzcn77.replugindemo.MainActivity$1.onClick(MainActivity.java:24)
                 at android.view.View.performClick(View.java:5198)
                 at android.view.View$PerformClick.run(View.java:21147)
                 at android.os.Handler.handleCallback(Handler.java:739)
                 at android.os.Handler.dispatchMessage(Handler.java:95)
                 at android.os.Looper.loop(Looper.java:148)
                 at android.app.ActivityThread.main(ActivityThread.java:5417)
                 at java.lang.reflect.Method.invoke(Native Method)
                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                 Suppressed: java.lang.ClassNotFoundException: com.qihoo360.plugin.app2.Entry
                 at java.lang.Class.classForName(Native Method)
                 at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
                 at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
                 at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                     ... 25 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

為什么?
再看看官方文檔翘狱,遺漏什么了秘案?沒有啊。
再看看官方文檔潦匈,還有沒看到的踏烙?沒有啊。
為什么历等?
再回想一下整個流程讨惩,gradle出錯,主題樣式錯誤寒屯,Didn't find class "com.qihoo360.plugin.app2.Entry
對荐捻,主題樣式黍少,這一環(huán)并沒有真正的解決。
找不到主題处面?application里面配置的有主題呀厂置。
把application的統(tǒng)一主題去掉,分別給每個activity配置主題魂角。
再來一次昵济,buildApk,導入主程序野揪,運行主程序访忿,調(diào)起,成功了K刮取:C!完美運行U醵琛N哉濉!
掌聲珍语,掌聲竖幔,掌聲

總結(jié)

首次的整個集成過程廊酣,也算是踩坑無數(shù),樂趣多多啊赏枚。希望Replugin項目組在后續(xù)的版本中能夠提供更多的功能亡驰,以及更高的穩(wěn)定性,當然也希望官方的Wiki再友好一點饿幅,能對一些集成規(guī)范的描述更詳細點唄凡辱。不過好用是真的。
作為行業(yè)大哥360開源出來的全面化插件機制栗恩,以及在360眾多項目中的實踐透乾,Replugin的功能性,肯定是毋庸置疑的磕秤,應用場景也必將十分廣泛乳乌。相信在未來很多項目中,會見到它的身影市咆。

網(wǎng)絡(luò)圖片
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汉操,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蒙兰,更是在濱河造成了極大的恐慌磷瘤,老刑警劉巖芒篷,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異采缚,居然都是意外死亡针炉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門扳抽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篡帕,“玉大人,你說我怎么就攤上這事贸呢×眨” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵贮尉,是天一觀的道長拌滋。 經(jīng)常有香客問我朴沿,道長猜谚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任赌渣,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忘晤。我一直安慰自己谷朝,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布鸿竖。 她就那樣靜靜地躺著沧竟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缚忧。 梳的紋絲不亂的頭發(fā)上悟泵,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音闪水,去河邊找鬼糕非。 笑死,一個胖子當著我的面吹牛球榆,可吹牛的內(nèi)容都是我干的朽肥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼持钉,長吁一口氣:“原來是場噩夢啊……” “哼衡招!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起每强,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蚁吝,失蹤者是張志新(化名)和其女友劉穎旱爆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窘茁,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡怀伦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了山林。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片房待。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖驼抹,靈堂內(nèi)的尸體忽然破棺而出桑孩,到底是詐尸還是另有隱情,我是刑警寧澤框冀,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布流椒,位于F島的核電站,受9級特大地震影響明也,放射性物質(zhì)發(fā)生泄漏宣虾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一温数、第九天 我趴在偏房一處隱蔽的房頂上張望绣硝。 院中可真熱鬧,春花似錦撑刺、人聲如沸鹉胖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甫菠。三九已至,卻和暖如春冕屯,著一層夾襖步出監(jiān)牢的瞬間寂诱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工愕撰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留刹衫,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓搞挣,卻偏偏與公主長得像带迟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子囱桨,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容