1.配置模块下的build.gradle文件:
apply plugin: 'com.android.application' def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) } android { compileSdkVersion 26 defaultConfig { applicationId "com.xx.xxxx" minSdkVersion 19 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { //Zipalign优化 zipAlignEnabled true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } applicationVariants.all { variant -> variant.outputs.all { // 输出apk名称为app_v1.0_2018-xx-xx_xxxx.apk def fileName = "app_${defaultConfig.versionName}_${releaseTime()}.apk" outputFileName = fileName } } sourceSets { main { jniLibs.srcDir 'libs' jni.srcDirs = [] } } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' compile 'org.greenrobot:eventbus:3.1.1' compile 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' implementation files('libs/tbs_sdk_thirdapp_v3.5.0.1004_43500.jar') }
android studio3.0 设置打包的apk文件名要在android{}代码块内如上所示,与2.x版本不同。
2.编写混淆配置文件proguard-rules.pro:
# Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile # 代码混淆压缩比,在0~7之间,默认为5,一般不做修改 -optimizationpasses 5 # 混合时不使用大小写混合,混合后的类名为小写 -dontusemixedcaseclassnames # 指定不去忽略非公共库的类 -dontskipnonpubliclibraryclasses # 这句话能够使我们的项目混淆后产生映射文件 # 包含有类名->混淆后类名的映射关系 -verbose # 指定不去忽略非公共库的类成员 -dontskipnonpubliclibraryclassmembers # 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。 -dontpreverify # 保留Annotation不混淆 -keepattributes *Annotation*,InnerClasses # 避免混淆泛型 -keepattributes Signature # 抛出异常时保留代码行号 -keepattributes SourceFile,LineNumberTable # 指定混淆是采用的算法,后面的参数是一个过滤器 # 这个过滤器是谷歌推荐的算法,一般不做更改 -optimizations !code/simplification/cast,!field/*,!class/merging/* ############################################# # # Android开发中一些需要保留的公共部分 # ############################################# # 保留我们使用的四大组件,自定义的Application等等这些类不被混淆 # 因为这些子类都有可能被外部调用 -keep public class * extends android.app.Activity -keep public class * extends android.app.Appliction -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 com.android.vending.licensing.ILicensingService # 保留support下的所有类及其内部类 -keep class android.support.** {*;} # 保留继承的 -keep public class * extends android.support.v4.** -keep public class * extends android.support.v7.** -keep public class * extends android.support.annotation.** # 保留R下面的资源 -keep class **.R$* {*;} # 保留本地native方法不被混淆 -keepclasseswithmembernames class * { native <methods>; } # 保留在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{ *** get*(); void set*(***); public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); } # 保留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 <fields>; !private <methods>; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); } # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆 -keepclassmembers class * { void *(**On*Event); void *(**On*Listener); } #内嵌类不能混淆 -keep class com.zbm.dainty.HistoryListAdapter$* { *; } -keep class com.zbm.dainty.QueryListAdapter$* { *; } -dontwarn com.tencent.smtt.export.external.** #忽略butterknife -keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; } #忽略eventbus -keepattributes *Annotation* -keepclassmembers class ** { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } #忽略百度定位sdk -keep class com.baidu.**{ *; } -keep interface com.baidu.**{ *; } -dontwarn com.baidu.**
#忽略百度语音识别sdk -keep class com.baidu.speech.**{*;}
#TBS X5 混淆规则 #-optimizationpasses 7 #-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -dontoptimize -dontusemixedcaseclassnames -verbose -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -dontwarn dalvik.** -dontwarn com.tencent.smtt.** #-overloadaggressively #@proguard_debug_start # ------------------ Keep LineNumbers and properties ---------------- # -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod -renamesourcefileattribute TbsSdkJava -keepattributes SourceFile,LineNumberTable #@proguard_debug_end # -------------------------------------------------------------------------- # Addidional for x5.sdk classes for apps -keep class com.tencent.smtt.export.external.**{ *; } -keep class com.tencent.tbs.video.interfaces.IUserStateChangedListener { *; } -keep class com.tencent.smtt.sdk.CacheManager { public *; } -keep class com.tencent.smtt.sdk.CookieManager { public *; } -keep class com.tencent.smtt.sdk.WebHistoryItem { public *; } -keep class com.tencent.smtt.sdk.WebViewDatabase { public *; } -keep class com.tencent.smtt.sdk.WebBackForwardList { public *; } -keep public class com.tencent.smtt.sdk.WebView { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.WebView$HitTestResult { public static final <fields>; public java.lang.String getExtra(); public int getType(); } -keep public class com.tencent.smtt.sdk.WebView$WebViewTransport { public <methods>; } -keep public class com.tencent.smtt.sdk.WebView$PictureListener { public <fields>; public <methods>; } -keepattributes InnerClasses -keep public enum com.tencent.smtt.sdk.WebSettings$** { *; } -keep public enum com.tencent.smtt.sdk.QbSdk$** { *; } -keep public class com.tencent.smtt.sdk.WebSettings { public *; } -keepattributes Signature -keep public class com.tencent.smtt.sdk.ValueCallback { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.WebViewClient { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.DownloadListener { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.WebChromeClient { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.WebChromeClient$FileChooserParams { public <fields>; public <methods>; } -keep class com.tencent.smtt.sdk.SystemWebChromeClient{ public *; } # 1. extension interfaces should be apparent -keep public class com.tencent.smtt.export.external.extension.interfaces.* { public protected *; } # 2. interfaces should be apparent -keep public class com.tencent.smtt.export.external.interfaces.* { public protected *; } -keep public class com.tencent.smtt.sdk.WebViewCallbackClient { public protected *; } -keep public class com.tencent.smtt.sdk.WebStorage$QuotaUpdater { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.WebIconDatabase { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.WebStorage { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.DownloadListener { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.QbSdk { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.QbSdk$PreInitCallback { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.CookieSyncManager { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.Tbs* { public <fields>; public <methods>; } -keep public class com.tencent.smtt.utils.LogFileUtils { public <fields>; public <methods>; } -keep public class com.tencent.smtt.utils.TbsLog { public <fields>; public <methods>; } -keep public class com.tencent.smtt.utils.TbsLogClient { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.CookieSyncManager { public <fields>; public <methods>; } # Added for game demos -keep public class com.tencent.smtt.sdk.TBSGamePlayer { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.TBSGamePlayerClient* { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.TBSGamePlayerClientExtension { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.TBSGamePlayerService* { public <fields>; public <methods>; } -keep public class com.tencent.smtt.utils.Apn { public <fields>; public <methods>; } -keep class com.tencent.smtt.** { *; } # end -keep public class com.tencent.smtt.export.external.extension.proxy.ProxyWebViewClientExtension { public <fields>; public <methods>; } -keep class MTT.ThirdAppInfoNew { *; } -keep class com.tencent.mtt.MttTraceEvent { *; } # Game related -keep public class com.tencent.smtt.gamesdk.* { public protected *; } -keep public class com.tencent.smtt.sdk.TBSGameBooter { public <fields>; public <methods>; } -keep public class com.tencent.smtt.sdk.TBSGameBaseActivity { public protected *; } -keep public class com.tencent.smtt.sdk.TBSGameBaseActivityProxy { public protected *; } -keep public class com.tencent.smtt.gamesdk.internal.TBSGameServiceClient { public *; } #--------------------------------------------------------------------------- #------------------ 下方是android平台自带的排除项,这里不要动 ---------------- -keep public class * extends android.app.Activity{ public <fields>; public <methods>; } -keep public class * extends android.app.Application{ public <fields>; public <methods>; } -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 -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepattributes *Annotation* -keepclasseswithmembernames class *{ native <methods>; } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } #------------------ 下方是共性的排除项目 ---------------- # 方法名中含有“JNI”字符的,认定是Java Native Interface方法,自动排除 # 方法名中含有“JRI”字符的,认定是Java Reflection Interface方法,自动排除 -keepclasseswithmembers class * { ... *JNI*(...); } -keepclasseswithmembernames class * { ... *JRI*(...); } -keep class **JNI* {*;}其中有忽略内嵌类,第三方butterknife,eventbus,百度定位sdk,百度语音识别sdk,TBS X5 WebView的混淆规则。
3.点击Build->Generate Signed APK;
填写密钥库信息;下一步是生成apk的存放位置,Signature Versions勾选V1+V2,Finish。
在app\build\outputs\mapping\release目录下可以里面有混淆前后文件的映射信息等文本文件,用于调试bug。