全面插件化時代RePlugin來臨

一哄褒、RePlugin簡介


RePlugin是一套完整的、穩(wěn)定的煌张、適合全面使用的呐赡,占坑類插件化方案。我們“逐>詞”拆開來解釋這個定義:

完整的:讓插件運行起來“像單品那樣”骏融,支持大部分特性
穩(wěn)定的:如此靈活完整的情況下链嘀,其框架崩潰率僅為業(yè)內(nèi)很低的“萬分之一”
適合全面使用的:其目的是讓應用內(nèi)的“所有功能皆為插件”
占坑類:以穩(wěn)定為前提的Manifest占坑思路
插件化方案:基于Android原生API和語言來開發(fā),充分利用原生特性

RePlugin:<a >Github地址</a>

RePlugin使用簡易示例:<a >Github地址</a>僅作為學習交流使用档玻,歡迎star

二怀泊、RePlugin配置說明


RePlugin分宿主工程和插件工程,需要在工程下配置以下內(nèi)容

1误趴、宿主工程配置


A)在Project級別gradle的dependencies中添加

classpath 'com.qihoo360.replugin:replugin-host-gradle:2.1.3'

B)在Moudle級別gradle中添加

apply plugin: 'replugin-host-gradle'
compile 'com.qihoo360.replugin:replugin-host-lib:2.1.3'

2霹琼、插件工程配置


A)在Project級別gradle的dependencies中添加

classpath 'com.qihoo360.replugin:replugin-plugin-gradle:2.1.4'

B)在Moudle級別gradle中添加

apply plugin: 'replugin-plugin-gradle'
compile 'com.qihoo360.replugin:replugin-plugin-lib:2.1.3'

三、RePlugin內(nèi)置插件


1凉当、內(nèi)置插件安裝


內(nèi)置插件以jar文件的形式放置在assets->plugins目錄下(注:內(nèi)置插件只有放在此目錄下才能被RePlugin識別并自動安裝枣申,如plugins文件夾未自動創(chuàng)建,需要手動創(chuàng)建)

2看杭、內(nèi)置插件識別機制


插件的相關配置信息采用json的格式進行存儲忠藤,存儲在assets->plugins-builtin.json文件下,程序啟動時楼雹,由RePlugin識別并自動進行插件安裝

  [{"high":null,
    "frm":null,
    "ver":100,
    "low":null,
    "pkg":"com.qihoo360.replugin.sample.demo1",
    "path":"plugins/demo1.jar","name":"demo1"
  }]

3模孩、內(nèi)置插件升級


A)主程序隨包升級

安裝包更新時,若插件版本更新時自動升級

B)通過install方法升級

同外置插件升級贮缅,RePlugin.install()方法進行插件升級

4榨咐、內(nèi)置插件刪除


直接移除jar文件即可,RePlugin會完成剩余操作

四谴供、RePlugin外置插件

1块茁、外置插件安裝


i. 外置插件安裝方式

采用加載apk的方式,使用RePlugin.install()方法進行安裝

ii. 外置插件安裝注意事項

如果處于debug模式憔鬼,需要在application中關閉簽名校驗龟劲,通過對RePluginConfig的處理,關閉簽名校驗轴或,(預計下個版本會默認關閉簽名校驗昌跌,不過官方建議在release中打開該校驗)

  @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //--------------開發(fā)的時候不驗證簽名
        RePluginConfig config = new RePluginConfig();
        config.setVerifySign(!BuildConfig.DEBUG);
        config.setPrintDetailLog(BuildConfig.DEBUG);
        config.setUseHostClassIfNotFound(true);
        RePlugin.App.attachBaseContext(this, config);    }

iii. 插件的安裝

通過RePlugin.install()方法進行安裝,可以通過RePlugin.preload()方法對插件進行預加載照雁,提升用戶體驗

  PluginInfo pluginInfo = RePlugin.install(absolutePath + "/aa.apk");
  if (pluginInfo != null) {
        Toast.makeText(MainActivity.this, "插件安裝成功",Toast.LENGTH_SHORT).show();
        boolean preload = RePlugin.preload(pluginInfo);   
 if (preload){
        Toast.makeText(MainActivity.this, "預加載完成", Toast.LENGTH_SHORT).show();
    } else {    
        Toast.makeText(MainActivity.this, "插件安裝失敗",Toast.LENGTH_SHORT).show();
    }

iiii. 插件的版本

需要Plugin的AndroidManifest中對插件的別名和版本進行設置蚕愤,不設置的話以包名和version為默認值(注:暫不支持同版本覆蓋,升級插件必須修改版本號饺蚊,卸載重新安裝也需要進行版本修改)

    <meta-data
        android:name="com.qihoo360.plugin.name"
        android:value="plugin01" />
    <meta-data
        android:name="com.qihoo360.plugin.version.ver"
        android:value="114" />

2萍诱、插件的升級


通過RePlugin.install(pi)方法進行升級

3、插件的卸載


通過RePlugin.uninstall("demo01")卸載

五污呼、RePlugin宿主與插件交互

1裕坊、宿主打開插件中的四大組件


A)Activity

  RePlugin.startActivity(MainActivity.this, RePlugin.createIntent("plugin01", "com.dg.replugindemo01.MainActivity"));

B)Service

  PluginServiceClient.bindService(RePlugin.createIntent( "exam", "AbcService"), mServiceConn);

B)Service

  PluginServiceClient.bindService(RePlugin.createIntent( "exam", "AbcService"), mServiceConn);

B)ContentProvider

  PluginProviderClient.query(xxx);

。燕酷。籍凝。。

2苗缩、宿主調用插件方法


A)fetchComponentList(String pluginName);//獲取插件的組件列表

B)fetchPackageInfo(String pluginName);//獲取插件的包信息

C)fetchResources(String pluginName);//獲取插件的資源信息

D)fetchClassLoader(String pluginName);//獲取插件的ClassLoader對象

E)fetchContext(String pluginName);//獲取插件的Context對象

F)fetchBinder(String pluginName, String module, String process);
//通過插件里的Plugin類饵蒂,獲取插件定義的IBinder

示例:

    //加載插件中的工具類
    ClassLoader classLoader = RePlugin.fetchClassLoader("plugin01");
    try {    
    Class<?> aClass = classLoader.loadClass("com.dgcredit.replugindemo01.DateHelper");   
    Method formatDate = aClass.getMethod("formatDate", Date.class); 
    String invoke = (String) formatDate.invoke(null, new Date()); 
    tvShow.setText(invoke);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

///加載插件,并獲取插件的資源信息

    Resources resources = RePlugin.fetchResources("plugin01");
    int identifier = resources.getIdentifier("icon_app", "drawable", "com.dgcredit.replugindemo01");
    ivShow.setImageResource(identifier);

3酱讶、插件調用宿主方法


//加載宿主中的工具類

  ClassLoader classLoader = RePlugin.getHostClassLoader();
    try {
        Class<?> aClass = classLoader.loadClass("com.dgcredit.repluginhostdemo.DateHelper");
        Method formatDate = aClass.getMethod("formatDate", Date.class);
        String invoke = (String) formatDate.invoke(null, new Date());
        viewById.setText(invoke);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

//加載宿主中圖片資源

  ClassLoader classLoader = RePlugin.getHostClassLoader();
    try{
        Class clazz = classLoader.loadClass("com.dgcredit.repluginhostdemo.R$drawable");
        Field field = clazz.getField("icon_app");
        int identifier = (int)field.get(null);
        ivShow.setImageResource(identifier);
    }catch(Exception e){
        Log.i("Loader", "error:"+Log.getStackTraceString(e));
    }

4退盯、插件調用宿主組件


  Intent intent = new Intent();
  intent.setComponentName(new ComponentName("com.qihoo360.replugin.sample.host", "com.qihoo360.replugin.sample.host.MainActivity"));
  context.startActivity(intent);

六、RePlugin接入錯誤集錦

1泻肯、Theme錯誤


  Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

解決方式

A)去除插件中對application的theme的引入渊迁,單獨對插件中的activity設置相關theme
   android:theme="@style/AppTheme"
B)在宿主的build.gradle中加入
  repluginHostConfig {
    useAppCompat = true
}

2、ActivityNotFoundException錯誤


Unable to find explicit activity class{com.qihoo360.replugin.sample.host/con.qihoo360.replugin.sample.host.loader.a.ActivityN1NRNTS3};have you declared this activity in your AndroidManifest.xml?
解決方式:
  關閉Setting中instand run功能灶挟。目前此Bug在官方2.1.4版本已修復宫纬,尚未驗證

3、Fail to apply plugin [id 'replugin-plugin-gradle']錯誤


解決方式:
 這個plugin需要放在android配置之后膏萧,因為需要讀取android中的配置項

4漓骚、外置插件RePlugin.install()方法無反應


解決方式:
@override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //-------------- 開發(fā)的時候不驗證簽名 -----------//
        RePluginConfig config = new RePluginConfig();
        config.setVerifySign(!BuildConfig.DEBUG);
        RePlugin.App.attachBaseContext(this, config);
        // =======================//
        }

文檔正在整理完善中,歡迎討論指正榛泛。蝌蹂。。曹锨。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孤个,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沛简,更是在濱河造成了極大的恐慌齐鲤,老刑警劉巖斥废,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異给郊,居然都是意外死亡牡肉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門淆九,熙熙樓的掌柜王于貴愁眉苦臉地迎上來统锤,“玉大人,你說我怎么就攤上這事炭庙∷橇” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵焕蹄,是天一觀的道長逾雄。 經(jīng)常有香客問我,道長腻脏,這世上最難降的妖魔是什么嘲驾? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮迹卢,結果婚禮上辽故,老公的妹妹穿的比我還像新娘。我一直安慰自己腐碱,他們只是感情好誊垢,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著症见,像睡著了一般喂走。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谋作,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天芋肠,我揣著相機與錄音,去河邊找鬼遵蚜。 笑死帖池,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的吭净。 我是一名探鬼主播睡汹,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼寂殉!你這毒婦竟也來了囚巴?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彤叉,沒想到半個月后庶柿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡秽浇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年浮庐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兼呵。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖腊敲,靈堂內(nèi)的尸體忽然破棺而出击喂,到底是詐尸還是另有隱情,我是刑警寧澤碰辅,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布懂昂,位于F島的核電站,受9級特大地震影響没宾,放射性物質發(fā)生泄漏凌彬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一循衰、第九天 我趴在偏房一處隱蔽的房頂上張望铲敛。 院中可真熱鬧,春花似錦会钝、人聲如沸伐蒋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽先鱼。三九已至,卻和暖如春奸鬓,著一層夾襖步出監(jiān)牢的瞬間焙畔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工串远, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宏多,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓澡罚,卻偏偏與公主長得像绷落,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子始苇,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

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

  • 前言 replugin-plugin-gradle 是 RePlugin 插件框架中提供給replugin插件用的...
    osan閱讀 7,088評論 8 33
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理砌烁,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,702評論 18 139
  • 引言 先簡單介紹一下Android插件化函喉。很早之前已經(jīng)有公司在研究這項技術避归,淘寶做得比較早,但淘寶的這項技術一直是...
    流水潺湲閱讀 11,418評論 8 149
  • 也許我們真的就像那路邊草管呵,忍受著塵土飛揚梳毙,還得盡力呼吸,忍受著風雨飄搖捐下,還得在每次的雨后账锹,奮力挺身,只為踮起腳尖感...
    stonerain閱讀 1,785評論 0 1
  • 圖圖今天主動向老師報告提問問題坷襟,又得了獎勵奸柬。估計自己畫的就是這內(nèi)容吧。
    綸綸媽閱讀 242評論 0 0