The introduction
In the last article, we studied the ClassLoader scheme design in hot repair, which is mainly used to load plug-ins.
Having seen how hosts load different plug-ins, let’s take a look at how plug-in programming is implemented, and how one of the famous Tencent teams (PS: said to be a business group of Tencent Video, etc.) uses plug-in to achieve dynamic design
The plugin programming
A flowchart
1) Plug-in project development is actually an APP project to realize plug-in business
2) During the development process, the plug-in needs to be constantly debugged to check whether the host load and use is normal. Then, the plug-in needs to be frequently copied to the place where the host can use it (such as: asset, etc.), which can be implemented with scripts
3) Host validation
Above is a brief overview of the process. Next, let’s look at the details and simple implementation of each process.
The plug-in project
Here is an APP module, which is mainly to realize the plug-in’s own business, such as: Cool Dog APP, there are modules such as listening to songs/live broadcast, each module is actually a plug-in APK
Plug-in related scripts
After the plugin function is developed, the plugin APK needs to be copied to the host project or other places for the host to load and use. This process involves the automation of scripts, such as the script of Shadow’s sample-Manager plugin APK (note that the following scripts are implemented in the host gradle file) :
1) In the gradle file of the host, the copy time of the plug-in is mounted in the build process of the host. This is convenient in the development process.
tasks.whenTaskAdded { task ->
if (task.name == "generateDebugAssets") {
generateAssets(task, 'debug')
}
if (task.name == "generateReleaseAssets") {
generateAssets(task, 'release')
}
}
Copy the code
2) Implementation of generateAssets:
/*** * 1)generateAssetsTask, system task anchor * 2)buildType, debug/release * */ def generateAssets(generateAssetsTask, buildType) { println "daviAndroid generateAssets" def moduleName = 'sample-manager' def pluginManagerApkFile = file("${project(":sample-manager").getBuildDir()}" + "/outputs/apk/${buildType}/" + "${moduleName}-${buildType}.apk") / / createCopyTask hung on in the generateAssetsTask, system task of anchor point "in the front of the generateAssetsTask. DependsOn createCopyTask (' : sample - the manager, buildType, moduleName, 'pluginmanager.apk', pluginManagerApkFile, "assemble${buildType.capitalize()}" ) }Copy the code
3) createCopyTask implementation:
// Add module apK (e.g. Sample copies - manager) to the project build/generated/assets/xx/def createCopyTask (projectName buildType, name, apkName, inputFile, taskName) { println "daviAndroid createCopyTask" def outputFile = file("${getBuildDir()}/generated/assets/${name}/${buildType}/${apkName}") outputFile.getParentFile().mkdirs() return tasks.create("copy${buildType.capitalize()}${name.capitalize()}Task", Copy) {group = 'build' description = "Copy ${name} into assets." from(inputfile.getparent ()) {include(inputfile.name) rename { outputFile.name } } into(outputFile.getParent()) }.dependsOn("${projectName}:${taskName}") }Copy the code
PS1: pay attention to this copy to the host of “build/generated/assets/xx/”, in the host read openAsset way, so the project need to be configured to assets
sourceSets {
debug {
assets.srcDir('build/generated/assets/sample-manager/debug/')
}
release {
assets.srcDir('build/generated/assets/sample-manager/release/')
}
}
Copy the code
PS2: PS2
validation
Above has completed the plug-in development, plug-in copy; The following is the host in the copy of the directory to load and use, about the loading method of the section has different ways, you can choose according to their own business needs, the specific code here >>
Plug-in to achieve dynamic design
background
We all know that a feature of Tencent’s Shadow framework is full dynamic design. The code of the plug-in framework (such as the configuration and upgrade of the plug-in) has become a part of the plug-in, and the implementation of iteration is no longer limited by the host packaging the old version of the plug-in framework
The configuration upgrade of the plug-in is implemented dynamically
Plug-in in the iterative process, there will be different business under the use of different plug-ins, so here it is necessary to achieve plug-in download/update logic;
Normally this logic is written in the host, but Shadow makes this logic dynamic through the plugin’s thinking, so that subsequent strategies are not confused when they need to be adjusted
Let’s take a look at how shadow is implemented, and explain the process according to the code, the code location is here >>
The implementation process
1) Design idea
A) Host: load the interface implementation in the plug-in in the way of interface dependence to realize the dynamic of the plug-in
B) Interface: Joe connects the host and plug-in
C) Plug-in: download plug-in services, preload other plug-ins, etc
If the download service or preload logic needs to be changed, you only need to change the implementation of the plug-in and deliver it again
2) Plug-in module
Here is the engineering architecture:
A) About constant, some constants
B) About dynamic-manager
The implementation mechanism of cross-process Service, plug-in loading and other services are based on such IPC scheme as the bearer
C) About manager
Plug-in load/update/download specific implementation classes, such as: load plug-in type/plug-in bean/ plug-in ZIP configuration description, etc
D) About dynamic-host
The first thing to note is that this module is only available to the plug-in at compile time, and then not to the plug-in, and the host public module
The main modules are public modules used by the host and the plug-in, such as the custom ApkClassLoader, which the host needs to load the plug-in, and the Sample-Manager plug-in manager, which needs to load other plug-ins
3) Host module
Here is the engineering architecture:
1) About app
Host startup module, involving the trigger plug-in update timing/plug-in copy to local, etc
2) About constant, some constants (and the plugin public module, see the plugin section above)
3) About dynamic-host
The main functions are described in the plugins section above, but the difference is that the module is plugged into the host
4) About Commons-io
File IO related libraries
At the end
Haha, that’s all for this article (systematic learning and growing together)
Tips
For more exciting content, please follow “DaviAndroid” wechat public account