这段配置,value那里就是wandoujia,360之类的渠道名称,但是我们在这里不会去写渠道名,写的是一个占位符,后面gradle编译的时候会动态的替换掉它。
- 在module(一般也就是app)的build.gradle的android{}中添加如下内容:
//productFlavors是android节点的一个自节点。你需要打什么渠道的包,就在这里按umeng的要求用渠道名给UMENG_CHANNEL_VALUE赋值。
/*productFlavors {
//方式1:里面是三个渠道
wandoujia {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: “wandoujia”]
}
xiaomi {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: “xiaomi”]
}
yingyongbao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: “yingyongbao”]
}
}*/
//优化1:上面只是三个渠道,如果有几十个渠道,都这样写,重复的东西太多,观察到每个渠道就是flavor的名称,所以修改如下:
/*productFlavors {
wandoujia {
//manifestPlaceholders = [UMENG_CHANNEL_VALUE: “wandoujia”]
}
xiaomi {
//manifestPlaceholders=[UMENG_CHANNEL_VALUE: “xiaomi”]
}
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}*/
//优化2:上面经过签名打包后生成的apk的名称是有默认命名规则的,
// 如:xxx-xiaomi-release.apk 但是我们想包含版本信息如:
// xxx-xiaomi-release-1.0.apk,所以最终打包脚本如下:
productFlavors {
wandoujia {
//manifestPlaceholders = [UMENG_CHANNEL_VALUE: “wandoujia”]
}
xiaomi {
//manifestPlaceholders=[UMENG_CHANNEL_VALUE: “xiaomi”]
}
}
//如果需要在不同渠道统一配置,使用productFlavors.all字段
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith(’.apk’)) {
def fileName = outputFile.name.replace(".apk", “-${defaultConfig.versionName}.apk”)
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
如果没有错误情况,我们会在Android studio的BuildVariant看到对应的渠道,如下图所示:
image.png
- 获取渠道
在代码中我们可以通过读取mate-data信息来获取渠道,然后添加到请求参数中,获取方法如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String channel=getChannel();
Toast.makeText(MainActivity.this, “channel==” + channel, Toast.LENGTH_SHORT).show();
}
private String getChannel() {
try {
PackageManager pm = getPackageManager();
ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
return appInfo.metaData.getString(“UMENG_CHANNEL”);
} catch (PackageManager.NameNotFoundException ignored) {
}
return “”;
}
然后再进行签名
签名配置
签名主要有两种方式:
-
手动签名打包
-
自动签名。
手动签名打包:
image.png
使用之前签名的文件,输入密码进行签名打包,如下图
image.png
选择打包渠道,如下图
image.png
finish后,生成apk文件,如下图
![](https://img-blog.csdnimg.cn/img_convert/b45d63ee2b4cff5c8efb
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
d4598997b6cb.webp?x-oss-process=image/format,png)
image.png
自动签名打包(通过命令的方式进行签名):
自动签名,是在我们的application中的build.gradle(Module:app),先配置好签名文件信息,我们要先创建好一个签名文件.
(1)加载Key Store:
我们先删掉上面的通过第一种方式所签名的apk文件。接下来进行第二种方式来签名,即命令行的方式。
打开Project Stucture图形化界面:
image.png
上图中,选中app这个module,然后切换到signing标签栏,紧接着点击添加,然后生成release签名信息,点击"OK"。
image.png
上图中,切换到Build Types标签,将Signing config选择为"release",即将刚刚生成的release签名信息配置进去。
操作完成之后,我们可以看到app这个module的build.gradle文件多出了如下红框部分的代码:
image.png
然后执行菜单栏的"build-clean Project":
image.png
(2)生成realease版本的apk:
在命令行Terminal输入如下命令:(AS已经将命令行Terminal集成到了软件当中)
gradlew assembleRelease
如果运行成功,效果如下:
image.png
项目/app/build/outputs/apk目录下
image.png
(3)为什么要使用gradlew命令而不是gradle命令:
在项目工程目录下有一个gradle文件夹,在gradle/wrapper目录下有一个gradle-wrapper.properties文件,打开:
image.png
上图代表着这个工程所依赖的gradle的版本信息。上图的红线表示,如果我们的工程中没有gradle,软件会根据这个url去下载gradle,终于知道为啥第一次打开AS时会这么慢了吧?
注意如果我们执行了gradlew命令,实际上是执行上面的gradle wrapper,然后找到我们已经下载好的gradle 2.2.1。如果现在有很多个工程,但是每个工程的gradle版本都不一样,我就必须要将每个版本的gradle都要配置到环境变量当中,而执行了gradlew命令,就会避免这个麻烦。
再把安装包在手机上安装即可。
缺点:
这样的打包方式效率比较低下,如果是几十个包还可以应付,打一个包快的话需要十几秒,慢的话需要几分钟不等,跟机器性能很有关系。
美团多渠道打包(速度比较快)
==============
原理
把一个Android应用包当作zip文件包进行解压,然后发现在签名生成的目录下(META-INF)添加一个空文件不需要重新签名。利用这个机制,该文件的文件名就是渠道名。这种方式不需要重新签名等步骤,非常高效。
优点:
这种打包方式速度非常快,900多个渠道不到一分钟就能打完
缺点:
1、google如果哪天更改打包规则,使得在META-INF中建立空文件还需要重新打包,这种方式将不可用
2、一些不法的渠道商很容易通过工具修改渠道,如果一个渠道商,通过网络劫持和篡改渠道的组合方式来获取暴利,对于程序开发者来说可能会存在着巨大的经济损失
如何使用
把需要打包的apk放在一个文件夹PythonTool下:
image.png
image.png
image.png
info文件夹下,czt.txt自动生成: