AS配置文件+gradle配置+混淆配置
1.Android Studio 配置文件:配置文件
2.gradle配置文件(可自行删减)
apply plugin: 'com.android.application'
//获取local.properties的内容
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
android {
compileSdkVersion 19
buildToolsVersion "25.0.2"
// 使用签名文件进行签名的两种方式
//第一种:使用gradle直接签名打包,配置keystore签名
signingConfigs {
release {
keyAlias '1.0'
keyPassword 'huyu'
storeFile file('E:/Studio_备份/xx/xx上传/xx.keystore')
storePassword 'huyu'
// v2SigningEnabled false //禁用V2签名模式,V2签名模式仅在7.0以上可以安装,减少APP安装过程时间和更多的保护机制
// 或者使用面板签名的时候,勾选V1,V2可以兼容各个版本
}
debug {
keyAlias 'androiddebugkey'
keyPassword 'android'
storeFile file('E:/Studio_备份/debug-keystore/huyu-debug.keystore')
storePassword 'android'
}
}
//第二种:为了保护签名文件,把它放在local.properties中并在版本库中排除,不把这些信息写入到版本库中(注意,此种方式签名文件中不能有中文)
// signingConfigs {
// config {
// keyAlias properties.getProperty("keystroe_keyAlias")
// keyPassword properties.getProperty("keystroe_keyPassword")
// storeFile file(properties.getProperty("keystroe_storeFile"))
// storePassword properties.getProperty("keystroe_storePassword")
// }
// }
defaultConfig {
applicationId "com.huyu.test"
minSdkVersion 15
targetSdkVersion 19
versionCode 20170505
versionName "2.04.170505"
// dex突破65535的限制
// 第一步:
// multiDexEnabled true
// 第二步: 在dependencies 添加依赖
// compile 'com.android.support:multidex:1.0.0'
// 第三步:
// Application继承一下MultiDexApplication即可。
}
//屏蔽lint的严格检查
lintOptions {
abortOnError false
disable 'MissingTranslation' // 防止在发布的时候出现因MissingTranslation导致Build Failed!
// checkReleaseBuilds false // 为了解决多个manifest中相同activity重复注册的问题(主要是用在多渠道配置不同的manifest文件)
}
//配置编译的jdk版本
// compileOptions {
// sourceCompatibility JavaVersion.VERSION_1_7
// targetCompatibility JavaVersion.VERSION_1_7
// }
/** 报 Duplicate files copied in APK META-INF/DEPENDENCIES File 1: xxx.jar File 2: xxx.jar
貌似说两个包里面的文件重复了*/
// packagingOptions {
// exclude 'META-INF/DEPENDENCIES'
// exclude 'META-INF/NOTICE'
// exclude 'META-INF/LICENSE'
// exclude 'META-INF/LICENSE.txt'
// exclude 'META-INF/NOTICE.txt'
// }
//打包配置debug模式下,使用正式版签名,此操作主要为了方便调试微信,新浪等第三方登录授权
buildTypes {
release {
minifyEnabled true
shrinkResources true //2.2版本该功能无法使用(必须和 minifyEnabled true 一起使用)
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
zipAlignEnabled false //默认是true, 只有显示配置为true时,才会生成unaligned.apk
minifyEnabled false //不启用混淆
shrinkResources false //默认是false, true为删除无用资源
signingConfig signingConfigs.debug //不配置签名项,会生成无签名的apk
// 动态在 BuildConfig.java 添加字段,在Java代码中调用 BuildConfig.FLAG_LOG
// buildConfigField "boolean", "FLAG_LOG", "true"
// buildConfigField "String", "API_HOST", "\"http://api.huyu.com\"" // 字符串变量
}
}
// 引用了 aar 资源1:需要加上下面这句;2.需要在 dependences 中加上 compile (name:'aar文件名', ext:'aar')
repositories {
flatDir {
dirs 'libs'
}
}
// sourceSets {
// baidu {
// // 设置不同的 AndroidManifest 文件
// // 一定要写相对路径,将原始manifest中的内容copy到为每个包单独配置的manifest中去,
// // 1.删除 AndroidManifest_baidu.xml 中配置包名的代码,因为已经在gradle.build中配置过了,不能重复配置
// // 2.在AndroidManifest_baidu.xml 中 application 标签下添加 tools:replace="android:label,android:icon"(具体可以参考报错信息)
// manifest.srcFile 'src/baidu/AndroidManifest_baidu.xml'
// java.srcDirs = ['src/baidu/java']
// res.srcDirs = ['src/baidu/res']
// assets.srcDirs = ['src/baidu/assets']
// }
// }
//配置多版本的apk, 需要在终端执行 gradlew assembleRelease 将生成不同渠道的release版apk
//不同的Flavor若需要对应不同的资源文件或者代码或者AndroidManifest.xml文件,均可以在src下简历对应flavor的文件夹,再覆盖资源即可。
//注意:覆盖资源的路径要与main下面路径一致
productFlavors{
baidu {
applicationId "com.huyu.baidu" //替换包名
// 动态在 BuildConfig.java 添加字段, 引用: BuildConfig.isGooglePlay
buildConfigField "boolean", "isGooglePlay", "false"
buildConfigField "String", "XIAOMI_APPID", '"你自己的key"'
buildConfigField "String", "XIAOMI_APPKEY", '"你自己的key"'
// 替换配置文件中的 ${app_name} 等占位符(${applicationId} 除外)
manifestPlaceholders = [
// app_icon: "@mipmap/ic_launcher",
app_name : "@string/app_name",
JPUSH_APPKEY : "你自己的key",
XIAOMI_APPID : "你自己的key",
XIAOMI_APPKEY : "你自己的key"
]
// resValue 动态在res/value/目录下根据第一个参数如 strings.xml 添加字段,所以添加前不能存在同名字段
// bools.xml 添加字段,所以添加前不能存在同名字段
// 在java代码中获取这里的配置属性: context.getResources().getString(R.string.isGooglePlayVersion);
// resValue("string" , "app_name","xx")
// resValue("bool" , "isGooglePlay", 'false')
}
google {
applicationId "com.huyu.gplay"
buildConfigField "boolean", "isGooglePlay", "true"
buildConfigField "String", "XIAOMI_APPID", '"你自己的key"'
buildConfigField "String", "XIAOMI_APPKEY", '"你自己的key"'
manifestPlaceholders = [
app_name : "@string/app_name_gplay",
JPUSH_APPKEY : "你自己的key",
XIAOMI_APPID : "你自己的key",
XIAOMI_APPKEY : "你自己的key"
]
}
}
//这里修改apk文件名
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "huyu_${variant.productFlavors[0].name}" +
"_V${defaultConfig.versionName}" +
"_${releaseTime() }.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
/**一般大多数是出现在图片上,.jpg修改成了.png就会出现这个问题*/
aaptOptions {
cruncherEnabled = false
useNewCruncher = false
}
}
// 定义一个打包时间
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile(name: 'BDUpdateSDK', ext: 'aar')
}
在项目根目录的 local.properties 中 添加如下信息(可以隐藏keystrore信息)
#对应自己实际的证书路径和名字,在这里由于签名文件是放在app目录下,因为没有写绝对路径。
keystroe_storeFile=E\:/Studio/keystore/huyu.keystore
keystroe_storePassword=huyu
keystroe_keyAlias=1.0
keystroe_keyPassword=huyu
3. 混淆配置文件(包含混淆规则和混淆配置)
######################################################################
#
# 1.语法规则
# (成员变量不管是否被引用,都不会删除,若指定就保留,未指定就重命名)
# 加 names 和 不加 names 区别:
# 不加 names: 当 类的成员没有被引用时,这个类不会被删除
# 加 names: 当 类的成员没有被引用时,这个类会被删除
#
# 关键字 1.压缩删除 2.类名是否保留(删除后) 3.成员是否保留(删除后) 描述
#
# keep 先删除 未被引用的方法 保留 再保留 指定成员名,最后重命名 其余成员名
#
# keepclassmembers 先删除 未被引用的方法 重名 再保留 指定成员名,最后重命名 其余成员名
#
# keepclasseswithmembers 先删除 未被引用的方法 指定成员存在就保留,不存在就重名 再保留 指定成员名,最后重命名 其余成员名
#
# keepnames 先删除 未被引用的方法 保留 再保留 指定成员名,最后重命名 其余成员名
#
# keepclassmembernames 先删除 未被引用的方法 重名 再保留 指定成员名,最后重命名 其余成员名
#
# keepclasseswithmembernames 先删除 未被引用的方法 指定成员存在就保留,不存在就重名 再保留 指定成员名,最后重命名 其余成员名
#
# -keepattributes attribute_name,... 保护给定的可选属性,例如LocalVariableTable,EnclosingMethod,
# Deprecated, Synthetic 等.
# -dontwarn [class_filter] 不打印指定类的警告信息(不是每个第三方SDK都需要-dontwarn,这取决于混淆时第三方SDK是否出现警告,需要的时候再加上)
#
#
# 通配符 描述
#
匹配类中的所有字段
#
匹配类中的所有方法
#
匹配类中的所有构造函数
# ? 匹配单个字符
# % 匹配任何基础类型的类型名
# * 匹配任意长度字符,但不含包名分隔符(.)。
# 比如说我们的完整类名是com.example.test.MyActivity,使用com.*,或者com.exmaple.*都是无法匹配的,因为*无法匹配包名中的分隔符,
# 正确的匹配方式是com.exmaple.*.*,或者com.exmaple.test.*,这些都是可以的。
# 但如果你不写任何其它内容,只有一个*,那就表示匹配所有的东西。
# *(当用在类里面时) 匹配任何字段和方法
# ** 匹配任意长度字符,并且包含包名分隔符(.)。
# 比如 android.support.** 就可以匹配android.support包下的所有内容,包括任意长度的子包。
# *** 匹配任意参数类型。
# 比如void set*(***)就能匹配任意传入的参数类型,*** get*()就能匹配任意返回值的类型。
# … 匹配任意长度的任意类型参数。
# 比如void test(…)就能匹配任意void test(String a)或者是void test(int a, String b)这些方法。
# $ 指内部类
#
#
#
# 2.不能混淆的代码
# 1.需要反射的代码
# 2.系统接口(AndroidMainfest 中的类(四大组件,Application 的子类), Framework 层下所有的类,support包, webview,js等)
# 3.Jni接口
# 4.需要序列号和反序列化的代码
# 5.与服务端进行元数据交互的实体类(JSON、XML中对应的实体类)
# 6.GSON、fastjson 等框架时,所写的 JSON 实体类
# 7.第三方库一般是不需要混淆的
#
######################################################################
######################################################################
#
# 1.特殊处理
#
# 实体类(在开发的时候我们可以将所有的实体类放在一个包内,这样我们写一次混淆就行了)
-keep public class com.huyu.entity.** {
public void set*(***);
public *** get*();
public *** is*();
}
# 接口(对外接口的public类名和成员名,否则外部无法调用)
-keep public interface com.huyu.interfaces.**{*;}
-keep public enum com.test.test.**{*;}
# 内部类或内部接口
-keep class com.huyu.utils.MyUtils$* {*;}
# 测试 keep
-keep class com.huyu.utils.TestKeep{
public void use2();
}
-keepclassmembers class com.huyu.utils.TestKeepclassmembers{
public void use2();
}
-keepclasseswithmembers class com.huyu.utils.TestKeepclasseswithmembers{
public void use1();
}
-keepnames class com.huyu.utils.TestKeepnames{
public void use2();
public void use4(int);
public void use5(int);
}
-keepclassmembernames class com.huyu.utils.TestKeepclassmembernames{
public void use2();
}
-keepclasseswithmembernames class com.huyu.utils.TestKeepclasseswithmembernames{
public void use1();
}
# 项目中其他Module的警告
#-dontwarn com.test.**
# 反射类
# 一般而言,使用反射一般会有以下方式,可以搜索代码,找到相关的类,然后在混淆配置里面进行保留
# Class.forName(“SomeClass”)
# SomeClass.class
# SomeClass.class.getField(“someField”)
# SomeClass.class.getDeclaredField(“someField”)
# SomeClass.class.getMethod(“someMethod”, new Class[] {})
# SomeClass.class.getMethod(“someMethod”, new Class[] { A.class })
# SomeClass.class.getMethod(“someMethod”, new Class[] { A.class, B.class })
# SomeClass.class.getDeclaredMethod(“someMethod”, new Class[] {})
# SomeClass.class.getDeclaredMethod(“someMethod”, new Class[] { A.class })
# SomeClass.class.getDeclaredMethod(“someMethod”, new Class[] { A.class, B.class })
# AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, “someField”)
# AtomicLongFieldUpdater.newUpdater(SomeClass.class, “someField”)
# AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, “someField”)
#
#-keep class com.huyu.reflectClass { *; } # 保留反射的 类名 和 类的所有成员
# js交互
# 在app中与HTML5的JavaScript的交互进行特殊处理,如
# package com.ljd.example;
#
# public class JSInterface {
# @JavascriptInterface
# public void callAndroidMethod(){
# // do something
# }
# }
# 我们需要确保这些js要调用的原生方法不能够被混淆,于是我们需要做如下处理
# -keepclassmembers class com.ljd.example.JSInterface {
#
;
# }
#
#
#
######################################################################
######################################################################
#
# 2.常用第三方jar处理
# (格式)
# -dontwarn com.alibaba.**
# -keep class com.alibaba.** {*;}
#
# 机智云
-dontwarn com.gizwits.**
-keep class com.gizwits.**{ *;}
# Volley
-keep class com.android.volley.** {*;}
-keep class com.android.volley.toolbox.** {*;}
-keep class com.android.volley.Response$* { *; }
-keep class com.android.volley.Request$* { *; }
-keep class com.android.volley.RequestQueue$* { *; }
-keep class com.android.volley.toolbox.HurlStack$* { *; }
-keep class com.android.volley.toolbox.ImageLoader$* { *; }
# N62
-keep public class com.p2p.core.MediaPlayer{
public private
; private int mNativeContext; } -keep public class com.p2p.core.VideoView{ public private
; } #pinyin4j -dontwarn net.soureceforge.pinyin4j.** -dontwarn demo.** -keep class net.sourceforge.pinyin4j.** { *;} -keep class demo.** { *;} -keep class com.hp.** { *;} #nineoldandroids -dontwarn com.nineoldandroids.* -keep class com.nineoldandroids.** { *;} # UIL -keep class com.nostra13.universalimageloader.** { *; } -keepclassmembers class com.nostra13.universalimageloader.** {*;} # 阿里产品(fastjson等) -dontwarn com.alibaba.** -keep class com.alibaba.** { *; } # 腾讯产品(QQ授权,微信授权等) -dontwarn com.tencent.** -keep class com.tencent.** {*;} # 百度产品(推送,自升级等) -dontwarn com.baidu.** -keep class com.baidu.**{*; } # 极光推送 -dontwarn cn.jpush.** -dontwarn cn.jiguang.** -keep class cn.jpush.** { *; } -keep class cn.jiguang.** { *; } # 小米推送 #可以防止一个误报的 warning 导致无法成功编译,如果编译使用的 Android 版本是 23。 -dontwarn com.xiaomi.push.** #这里 com.xiaomi.mipushdemo.DemoMessageRreceiver 改成 app 中定义的完整类名 #-keep class cn.jpush.android.service.PluginXiaomiPlatformsReceiver {*;} # 讯飞语音 -dontwarn com.iflytek.** -keep class com.iflytek.** {*;} # # ############################################################################# ###################################################################### # # 3.基础不用动的规则 # -dontskipnonpubliclibraryclasses # 不忽略非公共的库类 -dontskipnonpubliclibraryclassmembers # 指定不去忽略非公共库的类成员 -optimizationpasses 5 # 指定代码的压缩级别在0~7之间,默认为5,一般不做修改 -dontusemixedcaseclassnames # 不使用大小写混合,混合后的类名为小写 -dontpreverify # 混淆时不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度 -verbose # 混淆时记录日志 -dontoptimize # 不优化输入的类文件,优化选项是默认打开的(如果需要删除log,此选项需要去除) -keepattributes Signature # 不混淆泛型,如果混淆报错建议关掉 -keepattributes EnclosingMethod # 不混淆反射 -keepattributes *Annotation*,InnerClasses # 保持注解,内部类 -keepattributes SourceFile,LineNumberTable # 抛出异常时保留代码行号 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法(谷歌推荐) # 保留我们使用的四大组件,自定义的Application等等这些类不被混淆,因为这些子类都有可能被外部调用 -keep public class * extends android.app.Application -keep public class * extends android.app.Fragment -keep public class * extends android.app.Activity -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 com.android.vending.licensing.ILicensingService -keep public class com.google.vending.licensing.ILicensingService -keep public class * extends android.os.IInterface #记录生成的日志数据 -dump class_files.txt #列出 apk包内所有class的内部结构 -printseeds seeds.txt #列出 未混淆的类和成员 -printusage unused.txt #列出 未被使用的代码 -printmapping mapping.txt #列出 混淆前后的映射 -dontwarn android.support.** # 不提示兼容库的错误警告 -keep class android.support.** {*;} # 保留support下的所有类及其内部类 -keep public class * extends android.support.** # 保留support下v4,v7等子类 -keep class **.R$* {*;} # 保留R下面的资源 #保持 含有 native 函数 的 类 和 native 成员函数 不被混淆 -keepclasseswithmembernames class * { native
; } #保持Activity中的方法参数是view的方法,如 xml 布局使用了 doClick 等事件 -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } #保持 Parcelable 不被混淆 -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } #保持 Serializable 不被混淆 -keepnames class * implements java.io.Serializable #保持 Serializable 不被混淆并且enum 类也不被混淆 -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; !static !transient
; !private
; !private
; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); } # 保留枚举类不被混淆(如果报错,可以去掉这项) -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } # 保持自定义控件类不被混淆 -keepclasseswithmembers class * { public
(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public
(android.content.Context, android.util.AttributeSet, int); } -keep public class * extends android.view.View { *** get*(); void set*(***); public
(android.content.Context); public
(android.content.Context, android.util.AttributeSet); public
(android.content.Context, android.util.AttributeSet, int); } # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆 -keepclassmembers class * { void *(**On*Event); void *(**On*Listener); } #-----------处理webView处理--------------- -keepclassmembers class fqcn.of.javascript.interface.for.webview { public *; } -keepclassmembers class * extends android.webkit.webViewClient { public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap); public boolean *(android.webkit.WebView, java.lang.String); } -keepclassmembers class * extends android.webkit.webViewClient { public void *(android.webkit.webView, jav.lang.String); } # 移除一些log代码 -assumenosideeffects class android.util.Log { public static *** v(...); public static *** i(...); public static *** d(...); public static *** w(...); public static *** e(...); } # # # ######################################################################