唯一插件化RePlugin源码及原理深度剖析--工程职责及大纲
首先简单介绍一些Replugin,Replugin是360开源的Android插件化框架,它在2017年7月开源后,目前已经成为最火热的插件化框架之一,它的特点是唯一Hook,全工程只有一处Hook了系统类。这无形之中让插件化降低了门槛,以前需要实现插件化需要Hook很多系统类,如果你想Hook住系统类,那么首先你要了解系统类才行,而Replugin的唯一Hook点不但降低了插件化的门槛,而且对于稳定性也更强了
github地址:https://github.com/Qihoo360/RePlugin
再说一下写这一系列文章的的初衷,因为我之前也写过一个系列插件知识的博客,所以对插件化还算熟悉,当知道Replugin只hook了一个系统的类就实现了一个强大的插件化框架时,最开始只是想知道Replugin是如何Hook住系统的ClassLoader的,当我去看了这部分代码后,我惊讶了,区区不过几行代码而已(工具类不算),我当时想,这样就可以了吗?虽然知道了是如何hook住了系统的ClassLoader,但是并不知道底层是如何具体实现的,就这短短的几行代码吸引了我去看整个Replugin项目,当越往后看,越觉得Replugin的设计和android底层的很多原理共通,例如,Replugin管理多个插件的模式就像AMS管理我们app类似、插件的安装和系统安装应用类似、插件的加载和应用的启动过程类似等等,总之觉得看完Replugin的源码后会对理解android很多底层原理大有帮助,所以也有了这一系列的文章,本系列文章采用和系统源码对比分析的方式深入剖析Replugin的实现原理,在这个过程中,不但可以了解Replugin的实现原理,更能了解android的部分底层原理。
一、准备工作
本系列文章不只是对Replugin的源码读一遍,会结合系统源码更深入的理解其实现原理。所以需要有一定的基础,例如四大组件的运行过程、Binder机制、Android中ClassLoader加载dex及加载Class,动态
编译等。如果您对插件化的知识不是特别了解,建议移步我之前写过的插件化知识分解系列文章,文章并不是特别的深奥,只是从梳理插件化知识到最后实现可以很好的理清插件化的知识和原理,本系列文章
主要针对Replugin的lib库的源码分析,将会从初始化到使用的整个过程进行分析,而且初始化可以说是Replugin最重要的部分,初始化的过程中设计的框架初始化,hook模块,加载插件模块,这几个部分都非常的
重要,所以将他们拆分成3章来将,下面是本系列文章的大纲
唯一插件化Replugin源码及原理深度剖析–框架核心初始化
唯一插件化Replugin源码及原理深度剖析–唯一Hook点原理(会从系统源码的角度来分析)
唯一插件化Replugin源码及原理深度剖析–插件的安装、加载原理
二、工程职责介绍:
再开始源码阅读之前先介绍一下Replugin各个工程的职责
RePlugin共4个库工程,其中有两个是Gradle插件,2个java工程lib。然后主程序和插件工程分别占一个Gradle插件工程,和一个java工程lib。
1.replugin-host-gradle
2.replugin-host-library
3.replugin-plugin-gradle
4.replugin-plugin-library
从名字中我们可以明显的分出来前两个是主程序需要使用的库,而后两个是插件工程使用的,下面我们分别介绍每一个库的主要职责,等我们把他们的主要职责都介绍完了,整个Replugin的工作流程也就出来了。
1.replugin-host-gradle :
主程序使用的Gradle插件,主要职责是在我们的主程序打包的过程中(编译的过程中)动态的修改AndroidManifest.xml的信息,动态的生成占位各种Activity、provider和service的声明。
其次在还会动态生成一个HostBuildConfig的Java类,这个类是根据app下的build.gradle中配置的参数信息(repluginHostConfig)产生的,这个类的路径在BuildConfig的同级目录的gen包下
然后会扫描内置的插件目录assets\plugins目录,解析插件文件生成包含文件名、包名、版本、路径的plugins-builtin.json文件,这个文件的路径在asstts目录
2.replugin-host-library :
这个库是要由主程序依赖的,也是Replugin的核心,它的主要职责是初始化Replugin的整体框架,整体框架使用了Binder机制来实现多进程直接的的沟通和数据共享,或者说是插件之间和宿主之间沟通和数据共享,hook住ClassLoader,加载插件、启动插件、多插件的管理全部都与这个库辅助
3.replugin-plugin-gradle :
这个是插件工程使用的Gradle的插件,这个库使用了Transfrom API和Javassist实现了编译期间动态的修改字节码文件,主要是替换插件工程中的Activity的继承全部替换成Replugin库中定义的XXXActivity。动态的将插件apk中调用LocalBroadcastManager的地方修改为Replugin中的PluginLocalBroadcastManager调用,动态修改ContentResolver和ContentProviderClient的调用修改成Replugin调用,动态的修改插件工程中所有调用Resource.getIdentifier方法的地方,将第三参数修改为插件工程的包名
4.replugin-plugin-library :
这个库是由插件工程依赖的,这个库的主要目的是通过反射的方式来使用主程序中接口和功能,这个库在出程序加载加载插件apk后会进行初始化。
总结:我们通过介绍上面4个库的职责,那么我们就知道了Replugin的大体流程了,简单的概述:
其实Replugin还是使用的占坑的方式来欺骗系统,主工程在编译的时候会自动在AndroidManifest.xml中声明占坑组件的信息,然后在主工程运行的时候通过初始化Replugin hook住系统的ClassLoader,启动插件组件时将Intent中的信息替换为声明为占坑的信息,最后在加载组件的Class时,加载真正插件工程中的组件。被加载的插件工程是依赖的replugin-plugin-library的工程,其中Activity的继承关系被修改为了Replugin定义的XXXActivity,LocalBroadcastManager、ContentResolver和ContentProviderClient的调用全部被修改成了调用Replugin中的,这些操作全部是在打包的过程中自动完成的,插件工程中使用的Replugin的方法全部都是通过通过反射调用了主工程中的Replugin的接口。
二、准备工作
本系列文章不只是对Replugin的源码读一遍,会结合系统源码更深入的理解其实现原理。所以需要有一定的基础,例如四大组件的运行过程、Binder机制、Android中ClassLoader加载dex及加载Class,动态
编译等。如果您对插件化的知识不是特别了解,建议移步我之前写过的插件化知识分解系列文章,文章并不是特别的深奥,只是从梳理插件化知识到最后实现可以很好的理清插件化的知识和原理,本系列文章
主要针对Replugin的lib库的源码分析,将会从初始化到使用的整个过程进行分析,而且初始化可以说是Replugin最重要的部分,初始化的过程中设计的框架初始化,hook模块,加载插件模块,这几个部分都非常的
重要,所以将他们拆分成3章来将,下面是本系列文章的大纲
唯一插件化Replugin源码及原理深度剖析–框架核心初始化