当前位置:网站首页>The elegant combination of walle and Jianbao
The elegant combination of walle and Jianbao
2022-06-30 09:02:00 【Silent Pinocchio】
Multi channel packaging scheme , Now it is basically divided into Flavors And meituan walle The plan .
At first, my personal choice was Flavors The plan , stay gradle Configuration of the flavors, But soon found the disadvantages , Packing is slow , Especially execution assemble Mission , The six channels have been compiled for about ten minutes , This is absolutely unacceptable . Then they began to adopt meituan's walle, Here's the address first :
Blog address :https://tech.meituan.com/2017/01/13/android-apk-v2-signature-scheme.html
Github:https://github.com/Meituan-Dianping/walle
The principle of meituan's multi-channel packaging is also easy to understand :
Wally passed in Apk Medium
APK Signature BlockAdd customized channel information to the block to generate channel package , Thus, the generation efficiency of channel package is improved ,
Walle The configuration and use of are also very simple , No more introduction here , Please see the official document for details .
After multi-channel packaging , How to reinforce is still a problem , My reinforcement scheme adopts 360 Reinforcement scheme of reinforcement treasure , Reinforce one by one , It makes me feel like a waste of time , too troublesome , It's also true, a little low.
My initial idea was to pass a task Mission , To rely on walle Of assembleReleaseChannels Mission , Then traverse the multi-channel output path to traverse the multi-channel apk, For traversal reinforcement . Then it is found through practice , This scheme is not feasible , Reinforcement will report The following mistakes
Upload failed 10418 Submitted too often , Please try again later
Because the channel information is written in APK Signature Block In block ,apk The other information is the same , Reinforcement will also report the error of repeatedly submitting the same documents .
Upload failed 10419 The same documents are submitted frequently , Please try again later
besides , The reinforcement process can not avoid every apk All the upload , strengthening , download , The process of signing .
In addition to the problem of reinforcement , There will also be a serious problem , After re signing , The channel information fails . On this question , stay walle Of github It also explains this problem :
Wiki:https://github.com/Meituan-Dianping/walle/wiki/360 Reinforcement failure ?
stay Wiki in There are also great gods who have given solutions , But need Python Environmental Science , Forgive me for being a little lazy , This process makes me feel a little cumbersome .
This is not the optimal solution I want , So I found another way .
In the use of Walle In the process I found :
stay assembleReleaseChannels Mission It will be executed before execution assembleRelease Mission , This means that assembleReleaseChannels It depends on assembleRelease The task to perform ,assembleRelease The task will be outputs Build... Under the directory release package , then walle I'm using this apk To write multi-channel , that , Can we be in this primitive release apk Do something , take Multi channel packaging -> strengthening Process of Turn into strengthening -> Multi channel packaging . In this way, only the original apk Reinforce once , Then write the channel information , This greatly shortens the time of reinforcement , most important of all , Reinforce first , Write channel information after reinforcement , In this way, the channel information will not be covered .
The multi-channel packaging function is mainly composed of walle Plugins complete , So let's mainly look at this part of the process .
walle Project source code ,library moudle It is mainly open to users to read channel information , The concrete realization is in payload_reader in ,payload_writer moudle Its function is to write channel information ,walle-cli yes walle Command line program provided ,plugin It is the main plug-in of multi-channel packaging .
stay plugin in ,groovy Under the catalogue is The main implementation source code of the plug-in .
GradlePlugin It is the entrance of plug-in execution , Extension Mainly Gradle Configuration information ,ChannelMaker It's the main thing task Realization .
The realization of the plan , Mainly through modification Extension and ChannelMaker To achieve .
First look Extension
class Extension {
static final String DEFAULT_APK_FILE_NAME_TEMPLATE = '${appName}-${buildType}-${channel}.apk'
File apkOutputFolder
String apkFileNameFormat
File channelFile;
File configFile;
String variantConfigFileName;
......
}
Do these fields look familiar , you 're right , Just when we are gradle in To configure walle Information about
walle {
apkOutputFolder = new File("${project.buildDir}/outputs/channels")
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}- ${buildTime}-${flavorName}.apk'
//configFile And channelFile There must be one between the two , Otherwise, the channel package cannot be generated . When both exist, priority should be given to configFile
channelFile = new File("${project.getProjectDir()}/channel")
//configFile = new File("${project.getProjectDir()}/config.json")
}
We pass through here , You can configure the information of the reinforcement treasure
class Extension {
static final String DEFAULT_APK_FILE_NAME_TEMPLATE = '${appName}-${buildType}-${channel}.apk'
File apkOutputFolder
String apkFileNameFormat
File channelFile;
File configFile;
String variantConfigFileName;
// Reinforcement treasure jar route
String jiaguPath
// Reinforcement treasure user name
String jiaguUser
// Reinforcement treasure password
String jiaguPwd
}
And then the corresponding , We can do that gradle The corresponding configuration is carried out in
walle {
// Specify the output path of the channel package
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// Customized channel package APK File name for
apkFileNameFormat = '${appName}-${channel}-${buildType}-v${versionName}-${buildTime}.apk';
// Channel profile
channelFile = new File("${project.getProjectDir()}/channel")
jiaguPath ="/Users/wyl/Downloads/360jiagubao_mac/jiagu/jiagu.jar"
jiaguUser ="182xxxxx10"
jiaguPwd ="xixxxa1"
}
Then we'll see ChannelMaker
Here's the main thing packaging Method .
Extension extension = Extension.getConfig(targetProject);
This is what we got at gradle Information in configuration .
def iterator = variant.outputs.iterator();
while (iterator.hasNext()) {
def it = iterator.next();
def apkFile = it.outputFile
def apiIdentifier = null;
if (!it.outputs[0].filters.isEmpty()) {
def tempIterator = it.outputs[0].filters.iterator();
while (tempIterator.hasNext()) {
FilterData filterData = tempIterator.next();
if (filterData.filterType == "ABI") {
apiIdentifier = filterData.identifier
break;
}
}
}
if (apkFile == null || !apkFile.exists()) {
throw new GradleException("${apkFile} is not existed!");
}
}
Here is the result of traversing the build apk, Then on apk Conduct space judgment verification .
In fact, we know here , That's enough , Because the follow-up multi-channel , The channel number is written based on this apk To operate , As long as we add a reinforced process here, we can meet our needs .
First, create a folder , To store our reinforced apk file
def appFilePath = project.getProjectDir().absolutePath + "/build/outputs/jiagu"
File appDoc = new File(appFilePath)
if (!appDoc.exists()) appDoc.mkdir()
The method to get the signature is GrdlePlugin in It has been given to , You can use it directly
SigningConfig getSigningConfig(BaseVariant variant) {
return variant.buildType.signingConfig == null ? variant.mergedFlavor.signingConfig : variant.buildType.signingConfig;
}
Then the reinforcement operation can be carried out
if (extension.jiaguPath != null && extension.jiaguUser != null && extension.jiaguPwd != null) {
project.exec {
it.commandLine("java", "-jar", extension.jiaguPath, "-login", extension.jiaguUser, extension.jiaguPwd)
}
project.exec {
it.commandLine("java", "-jar", extension.jiaguPath, "-importsign", signingConfig.storeFile, signingConfig.storePassword, signingConfig.keyAlias, signingConfig.keyPassword)
}
def iterator = variant.outputs.iterator();
while (iterator.hasNext()) {
def it = iterator.next();
def apkFile = it.outputFile
project.exec {
it.commandLine("java", "-jar", extension.jiaguPath, "-jiagu", apkFile, appFilePath, "-autosign")
}
}
}
Then by traversing through the folder apk file , We can reinforce our apk Multi channel .
File[] files = appDoc.listFiles()
for (i in 0..<files.size()) {
File apkFile = files[i]
if (apkFile == null || !apkFile.exists()) {
throw new GradleException("${apkFile} is not existed!");
}
checkV2Signature(apkFile)
.......
}
The subsequent process is the same as the original process .
I'm through maven plug-in unit Publish the plug-in locally To test
In the plug-in directory build.gradle The dependence maven plug-in unit
apply plugin: 'maven'
Then configure the publishing information :
group = 'com.xl.channel-plugin'
version = "1.0.0"
// Package and upload to local
uploadArchives {
repositories {
flatDir {
dirs '../repo/'
}
}
}

Click this task , Publish plug-ins .
At the root gradle in Introduce warehouse address and plug-in
repositories {
google()
mavenCentral()
flatDir {
dirs './repo/'
}
}
classpath 'com.xl.channel-plugin:channel_plugin:1.0.0'
//app Of build.gradle in
apply plugin: 'xl-channel'
Then on walle To configure
walle {
// Specify the output path of the channel package
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// Customized channel package APK File name for
apkFileNameFormat = '${appName}-${channel}-${buildType}-v${versionName}-${buildTime}.apk';
// Channel profile
channelFile = new File("${project.getProjectDir()}/channel")
jiaguPath ="/Users/wyl/Downloads/360jiagubao_mac/jiagu/jiagu.jar"
jiaguUser ="182xxlxlxl10"
jiaguPwd ="xixixixi"
}

Then execute this task Let's test our results
Last in build/outputs Under the table of contents , One or two folders will be generated ,jiagu and channles .jiagu Stored reinforced apk,channels The storage is multi-channel apk.
thus , This plan is completed by standing on the shoulders of giants , Thanks to meituan walle.
Code address :https://github.com/WngYilei/ChannelReinforce
If you have any questions, please leave a message to discuss .
边栏推荐
- Metasploit practice - SSH brute force cracking process
- Flink Exception -- No ExecutorFactory found to execute the application
- Sort (simple description)
- Detailed explanation of pipline of mmdetection
- Flink SQL custom connector
- CUDA realizes L2 European distance
- Alcohol tester scheme: what principle does the alcohol tester measure alcohol solubility based on?
- Detectron2 source code reading 4-- registrar construction model
- Advanced technology management -- how managers design and build echelons
- Rew acoustic test (II): offline test
猜你喜欢

Bottomsheetbehavior principle of realizing the home page effect of Gaode map

C accesses mongodb and performs CRUD operations

Abstract factory pattern

Interpretation of source code demand:a rotation equivariant detector for aerial object detection

Flink Sql -- toAppendStream doesn‘t support consuming update and delete changes which

Pytorch BERT

Redis design and Implementation (III) | interaction between server and client (event IO model)

Detectron2 source code reading 4-- registrar construction model

Opencv learning notes -day8 (keyboard typing (waitkey()); Wait for typing) action: triggers some action when the appropriate character is typed using the keyboard)

Find the number that appears only once in the array
随机推荐
List set export excel table
[data analysis and display]
Flink Sql -- toAppendStream doesn‘t support consuming update and delete changes which
Opencv learning notes -day1 (image reading display imread, imshow, namedwindow)
Axure make menu bar effect
Esp32 things (3): overview of the overall system design
A troubleshooting of CPU bottom falling
Comparison of two ways for C to access SQL Server database (SqlDataReader vs SqlDataAdapter)
Rew acoustic test (I): microphone calibration
Explanation on the use of password profiteering cracking tool Hydra
Does the oscilloscope probe affect the measurement of capacitive load?
C accesses mongodb and performs CRUD operations
Esp32 things (VIII): music playing function of function development
基于Svelte3.x桌面端UI组件库Svelte UI
Opencv learning notes -day2 (implemented by the color space conversion function cvtcolar(), and imwrite image saving function imwrite())
Pytorch BERT
Anchorgenerator for mmdet line by line interpretation
Build a docker image of Henkel database from 0
Introduction to the runner of mmcv
Redis design and Implementation (IV) | master-slave replication