Android multi-channel fast packaging (claimed 900 channels in one minute)

1. Reason: Today I will talk about multi-channel fast packaging- Python script multi-channel packaging .

2. Background: Why do you want to talk about this? I believe that we all have the same troubles in Android development. When the project is launched, if the business of the project is large enough, the app requires dozens or even hundreds of channels to support these businesses. There are two types of traditional packaging:

1. AS's gradle configuration channel (channel) packaging. 2. Use the reinforcement tool (360 reinforcement tool) to create the channel package.

But what they all have in common is slowness . Not generally slow. It takes more than an hour to type out dozens of packages, and there is no guarantee that every package will be successful.

3. Solution: At first, we used Meituan’s Waliduo channel to package, but it requires gradle configuration, and it cannot be taken out as an independent tool.

Then I found out that another Python script package provided by Meituan is very fast, so it is necessary to talk about it.

4. Python script implementation:

  • First look at the directory:

  • Put the company's keystore file in the doc folder

  • lib into CheckAndroidV2Signature.jar and walle-cli-all.jar files.

  • ApkResiger.py is the configuration for running signatures, signature checks, write channels, alignment, etc.

  • channel is a collection of channel numbers.

  • config.py is the signature and path configuration.

  • Doumijagubao.apk is the apk package that you need to write to the channel. This apk needs to be reinforced without re-signing.

5. Detailed explanation of Python file configuration:

Detailed explanation of the config.py file:

#!/usr/bin/python
#-*-coding:utf-8-*-

#keystore信息
#Windows 下路径分割线请注意使用\\转义
keystorePath = "doc\debug.key"
keyAlias = ""
keystorePassword = ""
keyPassword = ""

#加固后的源文件名(未重签名)
protectedSourceApkName = "Doumijiagubao.apk"
#加固后的源文件所在文件夹路径(...path),注意结尾不要带分隔符,默认在此文件夹根目录
protectedSourceApkDirPath = ""
#渠道包输出路径,默认在此文件夹Channels目录下
channelsOutputFilePath = ""
#渠道名配置文件路径,默认在此文件夹根目录
channelFilePath = ""
#额外信息配置文件(绝对路径,例如/Users/mac/Desktop/walle360/config.json)
#配置信息示例参看https://github.com/Meituan-Dianping/walle/blob/master/app/config.json
extraChannelFilePath = ""
#Android SDK buidtools path , please use above 25.0+
sdkBuildToolPath = "C:\DMData\AndroidTools\\android-sdk-windows\\build-tools\\25.0.3"

Channel file details:

ApkResiger.py file details:

#!/usr/bin/python
#-*-coding:utf-8-*-

import os
import sys
import config
import platform
import shutil

#获取脚本文件的当前路径
def curFileDir():
     #获取脚本路径
     path = sys.path[0]
     #判断为脚本文件还是py2exe编译后的文件,
     #如果是脚本文件,则返回的是脚本的目录,
     #如果是编译后的文件,则返回的是编译后的文件路径
     if os.path.isdir(path):
         return path
     elif os.path.isfile(path):
         return os.path.dirname(path)

#判断当前系统
def isWindows():
  sysstr = platform.system()
  if("Windows" in sysstr):
    return 1
  else:
    return 0

#兼容不同系统的路径分隔符
def getBackslash():
	if(isWindows() == 1):
		return "\\"
	else:
		return "/"


# 清空临时资源
def cleanTempResource():
  try:
    os.remove(zipalignedApkPath)
    os.remove(signedApkPath)
    pass
  except Exception:
    pass

 # 清空渠道信息
def cleanChannelsFiles():
  try:
    os.makedirs(channelsOutputFilePath)
    pass
  except Exception:
    pass

# 创建Channels输出文件夹
def createChannelsDir():
  try:
    os.makedirs(channelsOutputFilePath)
    pass
  except Exception:
    pass


#当前脚本文件所在目录
parentPath = curFileDir() + getBackslash()

#config
libPath = parentPath + "lib" + getBackslash()
buildToolsPath =  config.sdkBuildToolPath + getBackslash()
checkAndroidV2SignaturePath = libPath + "CheckAndroidV2Signature.jar"
walleChannelWritterPath = libPath + "walle-cli-all.jar"
keystorePath = config.keystorePath
keyAlias = config.keyAlias
keystorePassword = config.keystorePassword
keyPassword = config.keyPassword
channelsOutputFilePath = parentPath + "channels"
channelFilePath = parentPath +"channel"
protectedSourceApkPath = parentPath + config.protectedSourceApkName


# 检查自定义路径,并作替换
if len(config.protectedSourceApkDirPath) > 0:
  protectedSourceApkPath = config.protectedSourceApkDirPath + getBackslash() + config.protectedSourceApkName

if len(config.channelsOutputFilePath) > 0:
  channelsOutputFilePath = config.channelsOutputFilePath

if len(config.channelFilePath) > 0:
  channelFilePath = config.channelFilePath


zipalignedApkPath = protectedSourceApkPath[0 : -4] + "_aligned.apk"
signedApkPath = zipalignedApkPath[0 : -4] + "_signed.apk"

# 创建Channels输出文件夹
createChannelsDir()

#清空Channels输出文件夹
cleanChannelsFiles()


#对齐
zipalignShell = buildToolsPath + "zipalign -v 4 " + protectedSourceApkPath + " " + zipalignedApkPath
os.system(zipalignShell)

#签名
signShell = buildToolsPath + "apksigner sign --ks "+ keystorePath + " --ks-key-alias " + keyAlias + " --ks-pass pass:" + keystorePassword + " --key-pass pass:" + keyPassword + " --out " + signedApkPath + " " + zipalignedApkPath
os.system(signShell)
print(signShell)

#检查V2签名是否正确
checkV2Shell = "java -jar " + checkAndroidV2SignaturePath + " " + signedApkPath;
os.system(checkV2Shell)

#写入渠道
if len(config.extraChannelFilePath) > 0:
  writeChannelShell = "java -jar " + walleChannelWritterPath + " batch2 -f " + config.extraChannelFilePath + " " + signedApkPath + " " + channelsOutputFilePath
else:
  writeChannelShell = "java -jar " + walleChannelWritterPath + " batch -f " + channelFilePath + " " + signedApkPath + " " + channelsOutputFilePath

os.system(writeChannelShell)

cleanTempResource()

print ("\n**** =============================TASK FINISHED=================================== ****\n")
print ("\n↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓   Please check channels in the path   ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n")
print ("\n"+channelsOutputFilePath+"\n")
print ("\n**** =============================TASK FINISHED=================================== ****\n")


6. Operation mode:

Open the command line --> cd to the parent directory of the script --> run python ApkResigner.py.

After success, you can send the first parent directory with an additional channels folder, which contains all channel packages. Is it soon?

If it works quickly, give it a thumbs up.

Download address : Python multi-channel packaging script

Guess you like

Origin blog.csdn.net/u010351988/article/details/87785517