android replugin插件化实践

    实际项目开发过程中经常会遇到和各种第三方app的对接,实际产品中也开发了SDK便于与第三方二次开发,但是这样第三方还是会有不少开发成本。件化的好处在于宿主和插件分开编译,宿主和插件的可以并行开发、互不干涉,宿主可以按实际需求进行相应插件的下载、安装及运行。网上开源的插件化框架也很多,都有各自的特点和不足,在项目中应客户的实际需求,采用了360的replugin插件化框架。

    Replugin是360手机卫士2017年开源的安卓插件化开发框架,属于占坑类插件化开发框架。相比于其他插件化方案,replugin的hook点更少,经过360手机卫士众多插件多年的验证,稳定性值得信赖。Replugin宿主无需升级,即可支持新增的四大组件,hook点只有Classloader一处,易于集成,插件管理稳定成熟,支持插件安装、升级、卸载、版本管理等。

1、replugin的接入

    对replugin插件的开发及集成进行了些研究,从小demo试验到将app相关组件进行插件化改造,并编写demo进行插件集成后的测试,将其中遇到的问题进行一些总结。

① 插件的开发

插件的接入主要是一些gradle配置,首先需要在项目工程的build.gradle文件(不是module的build.gradle文件)中添加360 replugin的gradle依赖,包括host和plugin的依赖。

然后在插件的build.gradle文件中添加相关配置,需要引入replugin的gradle插件,在repluginPluginConfig中配置插件的名称、包名及launcher activity,然后在dependencies中引入'com.qihoo360.replugin:replugin-plugin-lib:2.2.4'库。

插件gradle配置

    然后在插件的AndroidManifest.xml文件中进行配置,填写插件名称,”com.qihoo360.plugin.version.ver”的value为100,不做改动。    

插件的AndroidManifest文件

    以上配置完成后,插件的配置就算完成了,将插件打包成apk后将plugin1.apk后缀名改掉,改为plugin1.jar,插件的名称自己取。

② 宿主的接入

    宿主的接入包括gradle配置、application的继承以及插件的引入。

    在宿主module的build.gradle中引入replugin的host插件,在dependencies中引入库” com.qihoo360.replugin:replugin-host-lib:2.2.4”

宿主gradle配置

    然后在宿主的application中需要继承RePluginApplication并实现相应的接口,如果没采用继承方式的话,需要在application生命周期的方法中进行相应的一些初始化操作。这里采用继承的方式。最后将插件放到宿主的assets/plugins目录下。

插件存放目录

至此完成了宿主中插件的接入,而要在宿主中调起插件,只需启动插件的launcher activity。

插件启动方式

2、对接过程中遇到的问题

    宿主apk单独运行正常并不代表集成到宿主apk能运行不出差错。

① 权限问题

       插件中在AndroidManifest.xml中声明的权限,宿主中也相应要声明这些使用权限,或者动态检查申请权限。

② so库目录问题

    集成后开始运行,运行时发现了so库找不到的问题。

java.lang.UnsatisfiedLinkError: com.qihoo360.replugin.PluginDexClassLoader[DexPathList[[zip file "/data/data/hik.xxx/app_plugins_v3/xxx10-10-100.jar"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]] couldn't find "libstlport_shared.so"

at java.lang.Runtime.loadLibrary(Runtime.java:366)

at java.lang.System.loadLibrary(System.java:988)

    so库找不到的问题,一般是由于app中jniLibs下有多个so库目录,但实际的so库并没有这些目录中所有的cpu架构的so库,导致so库找不到。把app依赖的几个module都看了一遍后,发现确实有一个module中jniLibs目录下有除了armeabi及armeabi-v7a以外的目录,多了mips及x86目录,将其删了之后,重新编译插件,然后在宿主工程中运行,发现仍然报这个错误。最终查了些相关资料,自己尝试了多种方法后,发现要现在host的jniLibs目录下先定好所采用的cpu架构,并放上一个空so库文件进去。

so库

    LibNativeTest.so无任何实际用途,纯粹为了占坑。但为何是这样呢,这2天看了下replugin源码,偶然间瞥到如下中文注释。代码在PluginNativeLibsHelper.java中。

③ 资源未找到引起崩溃

资源未找到

    插件内部跳转,跳转到一个activity时报资源文件abc_fade_out.xml未找到引起崩溃,找了一圈发现abc_fade_out.xml并不是插件apk中引入的资源,而是系统资源。

    然错误提示指示系统的资源没找到,但实际问题肯定应该是自身程序代码问题导致的。定位到出问题的代码片段,打日志,发现确实在调用AudioPlayUtil.getInstance()之后就没往下执行了。那这个方法中究竟为何会导致崩溃呢。跟踪一下代码,看下整个的执行流程。

    如上图所示,AudioPlayUtil单例初始化时传入了application,在构造函数中,通过getApplicationContext获取到Context并保存起来,因为是资源找不到引起的问题,所以我们主要关注与资源相关的代码。得到上下文Context后,其中调用了context.getResources去拿资源,最终去res的raw目录找资源。插件运行没问题,但集成后运行出现了问题,而整个方法只有一个参数传进去。所以肯定是context出现了问题。

    实际运行中只是一个apk,一个应用,所以在activity中通过getApplication()获取到的是宿主的application而不是插件的。我们实际是想拿到插件中的资源,所以应该使用插件的上下文来获取。查找了RePlugin的相关api,发现只有一个getPluginContext()方法来获取插件的上下文。所以对代码进行了下改造,传入插件的上下文,资源获取问题得到解决。获取资源的地方很多,像很多Activity中使用getResources().getText()都没有报错,所以需要通过Context获取资源时,如果传入的是application上下文,则需要判断是宿主还是插件的上下文。

3、总结

   replugin的接入确实很方便,但是实际集成过程中还是会出现各种问题。replugin插件可以以两种方式进行集成,内置模式和外置模式,插件以内置模式方式进行集成时,需打包到宿主apk中。以外置方式插件可以下载后再安装、运行。插件化除了集成灵活外,插件有独立的版本号,升级时可以对插件独立进行升级而不需要整个app进行升级。而且各插件可以独立并行开发,增强开发效率。但同时插件化也有不少问题,插件化技术一般都使用了hook,针对不同手机厂商的定制安卓系统,兼容性需要经过测试检验,稳定性也可能会是个问题,而且如果出现了问题,排查问题时对开发者的技术要求更高。这只是简单的集成,集成后,插件宿主间通信等,还有很多细节还需继续深入。

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

推荐阅读更多精彩内容