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](https://github.com/Qihoo360/RePlugin/wiki/img/RePluginFramePic.jpeg)
4.SO?怎么用?
ok金矛,看完了官方介紹給我們畫的大餅芯急,現(xiàn)在看看怎么實現(xiàn)它,是的驶俊,坑來了娶耍。。
主程序的配置废睦,這里就不多說了伺绽。养泡。將RePlugin接入到您的主程序嗜湃,官方文檔描述的很清楚奈应,也沒有什么奇奇怪怪的錯誤。
主要來說說如何開發(fā)新的 RePlugin 插件购披,從RePlugin的Wiki我們可以看到杖挣,好簡單呀,就三步嘛刚陡,來吧惩妇。
然后我們碰到了.........
問題一:Gradle配置出錯
EXCUSE ME?那里有問題筐乳?再看看文檔歌殃,沒啥特別的描述呀。
然后蝙云,我在Issues里找到了官方項目組說的這一句:“這個要自動讀取前面build.gradle的配置內(nèi)容氓皱,如果放在前面,會讀為空勃刨。我們內(nèi)部討論過這個問題波材,如果要想自由放置就得傳參配置。當時考慮到盡量減少傳參配置就約定俗成讓放在文件末尾身隐。你可以看demo1廷区。”
好吧贾铝,既然如此能不能提一句只能放在文件末尾跋肚帷!
你是360垢揩,你老大大脉,我改!
水孩?镰矿?按你說的還不行?俘种?
然后秤标,我在Issues里看到了吃瓜群眾說的這一句:“你試試把apply plugin: 'replugin-plugin-gradle'
放在<apply plugin: 'com.android.application'
之前就好了,我的就是這樣好使的宙刘,你試試?”
抱著試一試的心態(tài)苍姜,然后我發(fā)現(xiàn)...成功了?悬包?說好的讀取配置內(nèi)容呢衙猪?說好的會讀為空呢?
OK,按照官方文檔垫释,各項都配置完成丝格,我們繼續(xù)進行。棵譬。
插件界面很簡單:
插件單獨運行一下显蝌,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界面依然如上歌逢。
然后我們發(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的功能性,肯定是毋庸置疑的磕秤,應用場景也必將十分廣泛乳乌。相信在未來很多項目中,會見到它的身影市咆。