加固+AndroidStudio原生的多渠道打包
1.为什么要加固?
由于安卓APP是基于Java的,所以极容易被破解,一个不经过加固的APP犹如裸奔一样,毫无防备。之前曾有新闻报道,一些专职的APP打包黑产就是专门从各种渠道找到apk,通过各种破解手段将apk文件破解、反编译,然后加入广告、病毒代码,重新打包投入市场,不明真相的用户将带病毒广告的apk下载下来,甚至因此造成利益损失。
对于移动应用开发工程师来说,应用自动化加固无疑是最便捷的一种安全方式了。通过加固可以在一定程度上达到反编译和防止被二次打包的效果。当然,现在网上很多平台都提供加固服务包括bat在内。加固原理差不多,但是加固强度和兼容性上还是有很大差别的。
2.市场上常见的一些加固产品
360加固保,爱加密,娜迦,梆梆,通付盾,阿里聚安全,腾讯云应用乐固
这是一篇对这些免费加固产品的对比介绍博客:https://www.cnblogs.com/baiqiantao/p/9286449.html
3.腾讯云应用乐固使用
3.1安装乐固
3.2注册腾讯云账号
3.3登录
03458b92-2184-4868-8c45-fc41f82d8739.png
3.4配置信息
a.配置加固后的应用存储位置
058ecd20-9a33-428a-9018-6ac564fe6bbd.png
b.配置签名信息
e90dc093-dbe1-442b-987e-077fc318a73d.png
c.如果需要多渠道打包(一般都要),配置多渠道信息,并打开开关
多渠道打包,要求在AndroidManifest.xml文件中配置如下信息,其中name是多渠道的渠道key(自定定义即可),value是渠道号,比如要打一个需要上传腾讯应用宝市场的应用包,value就需要改为:tencent,当然tencent可以自己取,aaa,bbb都可以,只要你认识就行,一般我们会使用对应市场的英文名称
<application
<meta-data
android:name="channel"
android:value="xts"/>
</application>
乐固多渠道打包时可以将清单文件中的渠道号改为你想要配置的
Android Name为清单文件中meta-data的key,
配置参数为你想要替换的渠道号,如果有多个,使用";"隔开
414bedf8-29ad-4382-8664-927466b5db67.png
3.5开始加固
点击添加应用,将你签好名的apk添加,然后坐等即可,完成后在你配置的 输出包的文件夹查看.
03458b92-2184-4868-8c45-fc41f82d8739.png
.AndroidStudio原生的多渠道打包
1.在清单文件中添加如下配置
${CHANNEL_VALUE}意思是引用build.gradle中的一个对象
<application>
....
<meta-data
android:name="channel"
android:value="${CHANNEL_VALUE}"/>
</application>
2.在Module级别的build.gradle里面配置如下信息
android {
...
productFlavors {
xiaomi {
//键要和清单文件里面的meta-data中的name一致
//value就是渠道号,可以自己定义
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
}
qh360 {
manifestPlaceholders = [CHANNEL_VALUE: "qh360"]
}
baidu {
manifestPlaceholders = [CHANNEL_VALUE: "baidu"]
}
wandoujia {
manifestPlaceholders = [CHANNEL_VALUE: "wandoujia"]
}
}
//多维度打包或者叫版本差异化打包,这里用不到,名字自己定义就好
flavorDimensions "every"
}
或者批量修改
productFlavors {
//渠道的渠道号
xiaomi {}
qh360 {}
baidu {}
wandoujia {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name]
}
flavorDimensions "every"
多维度理解
其实这涉及到了版本差异化打包的内容,如果说3.0以前的版本差异化打包更多的是为了厂商定制的,那么3.0以后的版本差异化打包就是在厂商的基础之上加入了机型,渠道等一些参数,变成了多个维度的产品。
也就是说之前的一个产品只有一个参数进行描述的话,现在就可以为其增加多个参数进行配置,比如A厂商的A渠道的A机型、A厂商的B渠道的C机型等,维度越多,产品的样式越发丰富。
3.开始打包
0cbfe482-5336-40b3-8a76-d92dab2273a1.png
55de1240-b120-499e-82a8-5f0623bac736.png
7f026293-d5e0-403a-a13d-b48056412938.png
4.代码获取渠道号
想要验证渠道号是否配置成功,需要获取渠道号并且吐司
/**
* 获取app当前的渠道号或application中指定的meta-data
*
* @return 如果没有获取成功(没有对应值,或者异常),则返回值为空
*/
public static String getAppMetaData(Context context, String key) {
if (context == null || TextUtils.isEmpty(key)) {
return null;
}
String channelNumber = null;
try {
PackageManager packageManager = context.getPackageManager();
if (packageManager != null) {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
if (applicationInfo != null) {
if (applicationInfo.metaData != null) {
channelNumber = applicationInfo.metaData.getString(key);
}
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return channelNumber;
}
//channel ,meta-data里面的name
ToastUtil.showShort(getAppMetaData(this,"channel"));
5.生产的apk改名
android {
...
//defaultConfig.versionName 版本名称
//releaseTime当前日期
//variant.productFlavors[0].name 渠道号
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "EveryWhereTrip_${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk"
}
}
}
}
}
// 获取当前系统时间
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}