作用:
1、统计用户安装APP来源
2、批量修改生成的apk文件名、包名等
签名:
1、生成jks(java key store):Build->Generate Signed Bundle
2、打包对应apk版本:AS编译器左侧,Build Variants中选择
3、查看MD5和SHA1:windows环境:cmd进入jdk的bin目录,执行keytool.exe -list -keystore D:\test.jks
具体配置:app目录下build.gradle文件
// 统一维度
flavorDimensions "versionCode"
// 1、配置多渠道
productFlavors {
xiaomi {
applicationId = "com.yong.xiaomi"
//不同渠道配置不同参数
buildConfigField "int", "TEST_VALUE", "1"
buildConfigField "String", "TEST_NAME", "\"xiaomi\""
}
huawei {
applicationId = "com.yong.huawei"
//不同渠道配置不同参数
buildConfigField "int", "TEST_VALUE", "2"
buildConfigField "String", "TEST_NAME", "\"huawei\""
}
//遍历productFlavors多渠道,设置渠道号(xiaomi 、huawei)
productFlavors.all {
flavor -> flavor.manifestPlaceholders.put("CHANNEL", name)
}
}
// 2、配置输出路径,项目名+编译类型+版本号+当前时间
applicationVariants.all { variant ->
def name = ((project.name != "app") ? project.name : rootProject.name.replace(" ", "")) +
"_" + variant.flavorName +
"_" + variant.buildType.name +
"_" + variant.versionName +
"_" + new Date().format(’yyyyMMddhhmm’) + ".apk"
//相当于路径 app/apk/
def path = "../../../../../apk/"
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith(’.apk’)) {
//指定路径输出
output.outputFileName = new File(path, name)
}
}
// 在打包完成后还可以做一些别的操作,可以复制到指定目录,或者移动文件到指定目录
/*variant.assemble.doLast {
//File out = new File("${project.rootDir}/apk")
variant.outputs.forEach { file ->
//1、复制apk到指定文件夹
//copy {
// from file.outputFile
// into out
//}
//2、把文件移动到指定文件夹
ant.move file: file.outputFile,
todir: "${project.rootDir}/apk"
}
}*/
}
// 3、多渠道签名的配置
signingConfigs {
xiaomi {
// keystore需要自己生成
storeFile file("../keystore/xiaomi.jks")
storePassword ’xiaomi’
keyAlias ’xiaomi’
keyPassword ’xiaomi’
v1SigningEnabled true //针对Jar包
v2SigningEnabled true //针对Apk包
}
huawei {
storeFile file("../keystore/huawei.jks")
storePassword ’huawei’
keyAlias ’huawei’
keyPassword ’huawei’
v1SigningEnabled true
v2SigningEnabled true
}
}
// 4、编译类型
buildTypes {
debug {
productFlavors.xiaomi.signingConfig signingConfigs.xiaomi
productFlavors.huawei.signingConfig signingConfigs.huawei
}
release {
minifyEnabled true // 开启混淆
zipAlignEnabled true // 优化apk文件
shrinkResources true // 去除无用资源
proguardFiles getDefaultProguardFile(’proguard-android.txt’), ’proguard-rules.pro’// 指定混淆规则文件
productFlavors.xiaomi.signingConfig signingConfigs.xiaomi
productFlavors.huawei.signingConfig signingConfigs.huawei
}
}
// 5、不同渠道不同资源文件配置
sourceSets {
xiaomi.res.srcDirs ’src/main/res-xiaomi’
huawei.res.srcDirs ’src/main/res-huawei’
}
配置:app目录下proguard-rules.pro文件,基本包含大多数场景
-ignorewarnings # 忽略警告,避免打包时某些警告出现
-optimizationpasses 5 # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontskipnonpubliclibraryclasses # 是否混淆第三方jar
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法
# 保留了继承自Activity、Application这些类的子类
# 因为这些子类有可能被外部调用
# 比如第一行就保证了所有Activity的子类不要被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class * extends android.support.v4.**
# 保留Activity中的方法参数是view的方法,
# 从而我们在layout里面编写onClick就不会影响
-keepclassmembers class * extends android.app.Activity {
public void * (android.view.View);
}
# 枚举类不能被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留自定义控件(继承自View)不能被混淆
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(***);
*** get* ();
}
# 保留Parcelable序列化的类不能被混淆
-keep class * implements android.os.Parcelable{
public static final android.os.Parcelable$Creator *;
}
# 保留Serializable 序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 对R文件下的所有类及其方法,都不能被混淆
-keep public class com.foresee.R$*{
public static final int *;
}
# 对于带有回调函数onXXEvent的,不能混淆
-keepclassmembers class * {
void *(**On*Event);
}
#实体类不混淆
-keep class com.yong.multichannel.** {*;}
#自定义控件不混淆
-keep class com.yong.multichannel.** {*;}