全面插件化时代RePlugin来临

一、RePlugin简介


RePlugin是一套完整的、稳定的、适合全面使用的,占坑类插件化方案。我们“逐>词”拆开来解释这个定义:

完整的:让插件运行起来“像单品那样”,支持大部分特性
稳定的:如此灵活完整的情况下,其框架崩溃率仅为业内很低的“万分之一”
适合全面使用的:其目的是让应用内的“所有功能皆为插件”
占坑类:以稳定为前提的Manifest占坑思路
插件化方案:基于Android原生API和语言来开发,充分利用原生特性

RePlugin:<a href="https://github.com/Qihoo360/RePlugin">Github地址</a>

RePlugin使用简易示例:<a href="https://github.com/aBenVip/RePluginHostDemo.git">Github地址</a>仅作为学习交流使用,欢迎star

二、RePlugin配置说明


RePlugin分宿主工程和插件工程,需要在工程下配置以下内容

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内置插件


1、内置插件安装


内置插件以jar文件的形式放置在assets->plugins目录下(注:内置插件只有放在此目录下才能被RePlugin识别并自动安装,如plugins文件夹未自动创建,需要手动创建)

2、内置插件识别机制


插件的相关配置信息采用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、内置插件升级


A)主程序随包升级

安装包更新时,若插件版本更新时自动升级

B)通过install方法升级

同外置插件升级,RePlugin.install()方法进行插件升级

4、内置插件删除


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

四、RePlugin外置插件

1、外置插件安装


i. 外置插件安装方式

采用加载apk的方式,使用RePlugin.install()方法进行安装

ii. 外置插件安装注意事项

如果处于debug模式,需要在application中关闭签名校验,通过对RePluginConfig的处理,关闭签名校验,(预计下个版本会默认关闭签名校验,不过官方建议在release中打开该校验)

  @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //--------------开发的时候不验证签名
        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);
        //-------------- 开发的时候不验证签名 -----------//
        RePluginConfig config = new RePluginConfig();
        config.setVerifySign(!BuildConfig.DEBUG);
        RePlugin.App.attachBaseContext(this, config);
        // =======================//
        }

文档正在整理完善中,欢迎讨论指正。。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容