前言:目前,Android 打渠道包 大多采用的友盟渠道
参考链接:
https://www.cnblogs.com/sunjiachen/p/11457630.html
第一步:在AndroidManifest中添加
<meta-data
android:name="UMENG_CHANNEL"
android:value="${channel}" />
第二步:在build.gradle中添加,baidu {}为指定渠道名称简写
build {
......
productFlavors {
baidu {}
xiaomi {}
qihu360 {}
yingyongbao {}
huawei {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL: name]
}
}
第三步:设置输出APK名称
build {
......
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName ="driver_${variant.productFlavors[0].name}_v${variant.versionName}.apk"
}
}
}
第四步:编译打包
选择不同渠道进行打包
这种方式存在打包效率慢,需要打多个渠道包会导致Android studio编译很长时间,很不舒服。
接下来使用python脚本打包,实现秒打包
思路:友盟统计最终都是 通过init设置渠道信息:如下,第三个参数是设置渠道名称的。
UMConfigure.init(
context,
umId,
ConstantCommon.CHANNEL,
UMConfigure.DEVICE_TYPE_PHONE,
""
)
如果我们在打包完成在apk里面添加一个空文件夹,命名为default,然后采用python脚本进行替换该文件夹名称为要打的渠道名称,再复制apk即为当前渠道包apk。最后app里面获取渠道名称, 使用读取该文件名称就可以对应当前渠道名称。
第一步:app里面获取对应渠道名称
/**
* 从apk中获取版本信息
* @param context
* @param channelKey
* @return
*/
fun getChannelFromApk(context: Context, channelKey: String): String { //从apk包中获取
val appInfo = context.applicationInfo
val sourceDir = appInfo.sourceDir
//默认放在meta-inf/里, 所以需要再拼接一下
val key = "META-INF/$channelKey"
var ret = ""
var zipfile: ZipFile? = null
try {
zipfile = ZipFile(sourceDir)
val entries: Enumeration<*> = zipfile.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement() as ZipEntry
val entryName = entry.name
if (entryName.startsWith(key)) {
ret = entryName
break
}
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
if (zipfile != null) {
try {
zipfile.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
//
val split = ret.split("_").toTypedArray()
//参数结构: key_{channel}
return if (split.size >= 2) {
split[1]
} else {
"default"
}
}
第二步:初始化友盟
/**
* 初始化友盟
*/
fun initUmeng(context: Context, umId: String) {
ConstantCommon.CHANNEL = AppUtils().getChannelFromApk(context, "channel")
UMConfigure.init(
context,
umId,
ConstantCommon.CHANNEL,
UMConfigure.DEVICE_TYPE_PHONE,
""
)
UMConfigure.setLogEnabled(BuildConfig.DEBUG)
}
第三步:编写python替换脚本
# 初始化少量渠道包的信息 格式为: channel,channel
def initChannelsSingle(channelName):
chs = channelName.split(',')
for channel in chs:
channels.append(channel)
def createChannelsApp(apkRootDir, apkName, channels):
for channel in channels:
print (channel)
#生成渠道包的文件名
desApkName = apkName.replace('default', channel)
print (desApkName)
apkSourcePath = apkRootDir + apkName #母包
apkDesPath = apkRootDir + desApkName #渠道包
if (apkSourcePath != apkDesPath):
print ('copy file')
shutil.copyfile(apkSourcePath, apkDesPath)
zipped = zipfile.ZipFile(apkDesPath, 'a', zipfile.ZIP_DEFLATED)
fileName = "channel_{}".format(channel)
print (fileName)
f = open(fileName, 'w')
f.close()
empty_channel_file = "META-INF/" + fileName
zipped.write(fileName, empty_channel_file)
# 方法用于删除指定路径的文件
# os.remove(fileName)
第四步:进行打包
先本地打出apk,然后执行脚本
如:python createChannelPackage.py all app\build\outputs\apk\_default\release\ comic-default-release-v1.0.0.apk
all 对应 打所有渠道包,app\build\outputs\apk\_default\release\对应 apk包所在的目录,release-v1.0.0.apk 对应文件名
python 对应下载链接:
https://download.csdn.net/download/qq_28759359/20701344
对应渠道包下载链接:
https://download.csdn.net/download/qq_28759359/20701433
渠道包格式为xx,xx…自己可以随便写对应渠道。多个渠道基本都是几秒钟时间打完。