1.為什么要加固?
由于安卓APP是基于Java的,所以極容易被破解,一個不經過加固的APP猶如裸奔一樣,毫無防備。之前曾有新聞報道,一些專職的APP打包黑產就是專門從各種渠道找到apk,通過各種破解手段將apk文件破解、反編譯,然后加入廣告、病毒代碼,重新打包投入市場,不明真相的用戶將帶病毒廣告的apk下載下來,甚至因此造成利益損失。
對于移動應用開發(fā)工程師來說,應用自動化加固無疑是最便捷的一種安全方式了。通過加固可以在一定程度上達到反編譯和防止被二次打包的效果。當然,現在網上很多平臺都提供加固服務包括bat在內。加固原理差不多,但是加固強度和兼容性上還是有很大差別的。
2.市場上常見的一些加固產品
360加固保,愛加密,娜迦,梆梆,通付盾,阿里聚安全,騰訊云應用樂固
這是一篇對這些免費加固產品的對比介紹博客:https://www.cnblogs.com/baiqiantao/p/9286449.html
3.騰訊云應用樂固使用
3.1安裝樂固
3.2注冊騰訊云賬號
3.3登錄

3.4配置信息
a.配置加固后的應用存儲位置

b.配置簽名信息

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,
配置參數為你想要替換的渠道號,如果有多個,使用";"隔開

3.5開始加固
點擊添加應用,將你簽好名的apk添加,然后坐等即可,完成后在你配置的 輸出包的文件夾查看.

.AndroidStudio原生的多渠道打包
別忘了先配置簽名文件
創(chuàng)建自己的jks簽名文件
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機型等,維度越多,產品的樣式越發(fā)豐富。
3.開始打包



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 {
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
// variant.buildType.name 當前是 debug 還是 release
// defaultConfig.versionName 版本名稱
// gitCurrentBranchName() 當前分支的名稱
// variant.productFlavors[0].name 渠道號
// releaseTime 當前日期
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "EveryWhereTrip-" + variant.buildType.name + "-v" + defaultConfig.versionName + "-" + gitCurrentBranchName() + "-" + variant.productFlavors[0].name + "-" + releaseTime() + ".apk"
}
}
}
//獲取當前分支名稱
def static gitCurrentBranchName() {
def cmd = 'git symbolic-ref --short -q HEAD'
def branchName = cmd.execute().text.trim()
return branchName
}
// 獲取當前系統時間
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
android studio設置生成的release版本apk的名稱
Android Stdio 如何自定義生成APK的名稱