一、前言
Replugin是在2017年7月份由360公司推出的开源插件化技术。号称支持App“全面插件化”。目前Replugin项目release版本已经升级到v2.2.1,wiki上维护的项目介绍以及FAQ较为全面,360团队对此开源项目还是有投入人力支撑的,很适合对插件化感兴趣的同学学习研究。
github地址:
https://github.com/Qihoo360/RePlugin
二、 特点
1. Replugin插件化技术的Hook点只有一处,这也是Replugin相比其他主流插件化技术最具特色的一点。其只Hook了系统ClassLoader,没有hook任何的系统Binder。对于系统侵入较小,稳定性和系统兼容性无疑得到了保证。
2. 采用的是较典型的占坑类插件化思路,在Manifest中提前补上“坑位Activity”。在启动插件Activity的时候会在调用AMS接口之前用坑位
Activity
去替换,然后再AMS回调应用进程去创建Activity的时候恢复为插件
Activity
,从而达到对系统瞒天过海的目的。
3. 提出了利用gradle构建技术的动态编译方案,新增了replugin-host-gradle和replugin-plugin-gradle两个gradle插件,在工程编译过程中实现对宿主apk或者插件apk进行自动化适配,无需再代码逻辑上做任何修改。对于apk本身而言可以是单品也可以作为插件。
(个人觉得最实用的一点)
三、相关知识
1. Android ClassLoader
2. Hook技术
3. gradle动态构建
四、目录结构
Replugin在github中的目录结构主要分为4个module,其中两个gradle module: replugin-host-gradle和replugin-plugin-gradle, 两个library库:replugin-host-library和replugin-plugin-library。
1. replugin-host-gradle
这是一个gradle插件,作用于host宿主app,主要在host应用编译期间的构建任务流中插入一些自定义的任务,已实现对host应用适配插件化的相关配置,从而达到自动化适配的目的,主要利用的是gradle构建的相关知识点,修改内容发生在编译期间,具体逻辑是由groovy实现,
代码实现文件:
RePlugin
/
replugin-host-gradle
/
src
/
main
/
groovy
/
com
/
qihoo360
/
replugin
/
gradle
/
host
/RePlugin.groovy
改动内容包括如下:
a. 根据宿主build.gradle中配置的
repluginHostConfig
相关属性去自动生成一个与BuildConfig.java同级目录下的名为
RepluginHostConfig
的java文件
b. 利用gradle动态编译技术实现对
Manifest
文件相关内容补充,其中坑位
Activity
、
Provider
等都在此gradle插件中实现
Manifest
配置。反编译一下生成的apk查看下
Manifest
内容发现多出了很多配置。
c. 然后还会扫描宿主位于asset/plugins目录下的内置插件并且讲所有内置插件相关信息打包自动生成plugins-builtin.json文件中去,后续加载内置插件信息会从此文件中读取。
2. replugin-plugin-gradle
这个gradle作用于插件apk,主要是在插件app编译期间利用
Transform api
在class文件转换为dex文件之前对Java 字节码文件进行操作,利用Java字节码库
Javaassist
进行代码注入,从而达到不修改插件apk工程源码前提下载编译器对插件apk进行动态修改的目的。
修改内容包括:
a. 将插件中所有的XXXActivity类中的*XXXActivity父类修改为插件库replugin-plugin-library中的XXXPluginActivity类,反编译看看就能发现最终插件apk的各个Activity继承了XXXPluginActivity父类。
b. 实现替换插件中的
LocalBroadcastManager
方法调用为插件库的
PluginLocalBroadcastManager
中的方法调用。
c. 替换插件中的
ContentResolver
相关方法调用为插件库的
PluginProviderClient
类的对应方法。
上述两个gradle插件实现了
Replugin
动态编译的能力,具体实现细节可以参考下面的博客,讲解的很详细,对于学习groovy使用和如何灵活运用gradle构建都有一定的借鉴意义。
replugin源码解析之replugin-host-gradle(宿主的gradle插件)
replugin源码解析之replugin-plugin-gradle(插件的gradle插件)
3.
replugin-host-library
这个Java库作用于host宿主应用,是整个Replugin的核心库,来实现
Replugin
相关基础类的初始化,提供宿主应用注入
Replugin
入口
RepluginApplication
类,hook掉系统的
ClassLoader
,提供host应用相关开发API来实现Replugin接入,利用aidl实现跨进程通信来实现对插件的管理、加载、卸载、升级等操作都依赖于这个库。
build.gradle对应的依赖是compile 'com.qihoo360.replugin:replugin-host-lib:XXX
4.replugin-plugin-library
这个Java库作用于plugin应用,主要提供各种插件基类如
PluginActivity
等,并利用反射技术来实现对replugin-host-lib相关接口的调用,来保证插件内部的组件能够如图宿主一样正常运行。
其中的
RePlugin
、
RePluginInternal
、
PluginServiceClient
都是反射宿主App :
replugin-host-library
中的
RePlugin
、
RePluginInternal
、
PluginServiceClient
类方法。
这个库在插件被加载时候会被初始化。
build.gradle对应的依赖是compile 'com.qihoo360.replugin:replugin-plugin-lib:XXX
总结:
通过对上述目录结构的分析,整个
Replugin
架构的轮廓应该是很清晰简单的,首先就是编写了两个gradle插件库,利用gradle的动态编译能力在编译期间动态注入对宿主和插件的修改,从而达到了无需修改任何工程代码就能自动化完成工程的Replugin适配;利用提前在
Manifest
中占坑的“坑位“和hook系统
ClassLoader
方式去来实现对插件中组件的替换和恢复,以实现对系统的瞒天过海;