標籤:
AndroidStudio中的項目可以用compile的形式引入github上的開 源項目,可以引用module,而不一定都要用libs檔案夾中添加jar包的形式。在最終realease打包時,混淆的設定是比較重要的,否則會導致 產生的包有很多功能不能正常使用。下面列舉一個基本的app的build.gradle和混淆檔案。並注意,混淆打包後的apk檔案大小會比不使用混淆要 小。
在app根目錄下設定build.gradle和混淆檔案,然後把混淆選項寫入混淆檔案就可以。雖然app項目中可能引用了一些module,但這些module工程可以不定義自己的混淆,我的工程目錄結構如下:
其中app是應用主模組,引用剩餘的module,被引用module的build.gradle中都使用預設的設定不啟用混淆:
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘ } }
在主目錄的build.gradle:
apply plugin: ‘com.android.application‘def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))}repositories { maven { url ‘https://oss.sonatype.org/content/repositories/snapshots‘ }}android { compileSdkVersion 22 buildToolsVersion ‘22.0.1‘ defaultConfig { applicationId "com.*****.****" //自己的applicationId minSdkVersion 14 targetSdkVersion 19 versionCode 1 versionName "1.0" } //執行lint檢查,有任何的錯誤或者警告提示,都會終止構建,我們可以將其關掉。 lintOptions { abortOnError false } //簽名 signingConfigs { debug { } release {// 自己的簽名檔案 storeFile file("doc/****.jks") storePassword "******" keyAlias "******" keyPassword "******" } } buildTypes { debug { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" versionNameSuffix "-debug" minifyEnabled false zipAlignEnabled false shrinkResources false signingConfig signingConfigs.debug } release { // 不顯示Log buildConfigField "boolean", "LOG_DEBUG", "false" //混淆 minifyEnabled true //Zipalign最佳化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //前一部分代表系統預設的android程式的混淆檔案,該檔案已經包含了基本的混淆聲明,後一個檔案是自己的定義混淆檔案 proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘ //簽名 signingConfig signingConfigs.release applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith(‘.apk‘)) { // 輸出apk名稱為app_v1.0_2015-xx-xx_xxxx.apk //def fileName = "app_v${defaultConfig.versionName}_${releaseTime()}.apk" def fileName = "app_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk" output.outputFile = new File(outputFile.parent, fileName) } } } } } //渠道Flavors,配置不同風格的app,友盟渠道統計時用到 productFlavors { "offical" {} "360" {} yingyongbao {} wandoujia {} baidu {} "91" {} }}dependencies { compile fileTree(dir: ‘libs‘, include: [‘*.jar‘]) compile project(‘:appsdk‘) compile ‘com.jakewharton:butterknife:7.0.1‘ //compile ‘com.faradaj:blur-behind:1.1‘ compile ‘com.github.ksoichiro:android-observablescrollview:1.6.0‘ compile ‘com.nineoldandroids:library:2.4.0‘ compile ‘in.srain.cube:ultra-ptr:1.0.10‘ compile ‘com.android.support:cardview-v7:22.1.0‘ compile project(‘:multi-image-selector‘)}
proguard-rules.pro檔案中則定義了項目的混淆選項,定義如下:
# Add project specific ProGuard rules here.# By default, the flags in this file are appended to flags specified# in D:\Android\sdk/tools/proguard/proguard-android.txt# You can edit the include path and order by changing the proguardFiles# directive in build.gradle.## For more details, see# http://developer.android.com/guide/developing/tools/proguard.html# Add any project specific keep options here:# 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 *;}#指定代碼的壓縮層級-optimizationpasses 5#包明不混合大小寫-dontusemixedcaseclassnames#不去忽略非公用的庫類-dontskipnonpubliclibraryclasses #最佳化 不最佳化輸入的類檔案-dontoptimize #預校正-dontpreverify #混淆時是否記錄日誌-verbose # 混淆時所採用的演算法-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*#保護註解-keepattributes *Annotation*# 保持哪些類不被混淆-keep public class * extends android.app.Fragment-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 com.android.vending.licensing.ILicensingService#如果有引用v4包可以添加下面這行-keep public class * extends android.support.v4.app.Fragment#忽略警告-ignorewarning##記錄產生的日誌資料,gradle build時在本項目根目錄輸出###apk 包內所有 class 的內部結構-dump proguard/class_files.txt#未混淆的類和成員-printseeds proguard/seeds.txt#列出從 apk 中刪除的代碼-printusage proguard/unused.txt#混淆前後的映射-printmapping proguard/mapping.txt########記錄產生的日誌資料,gradle build時 在本項目根目錄輸出-end#######如果引用了v4或者v7包-dontwarn android.support.**####混淆保護自己項目的部分代碼以及引用的第三方jar包library-end#####保持 native 方法不被混淆-keepclasseswithmembernames class * { native <methods>;}#保持自訂控制項類不被混淆-keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet);}#保持自訂控制項類不被混淆-keepclassmembers class * extends android.app.Activity { public void *(android.view.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*(...);}#保持 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 <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();}#保持枚舉 enum 類不被混淆-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String);}-keepclassmembers class * { public void *ButtonClicked(android.view.View);}#不混淆資源類-keepclassmembers class **.R$* { public static <fields>;}#避免混淆泛型 如果混淆報錯建議關掉#-keepattributes Signature#移除Log類列印各個等級日誌的代碼,打正式包的時候可以做為禁log使用,這裡可以作為禁止log列印的功能使用,另外的一種實現方案是通過BuildConfig.DEBUG的變數來控制#-assumenosideeffects class android.util.Log {# public static *** v(...);# public static *** i(...);# public static *** d(...);# public static *** w(...);# public static *** e(...);#}##################################################################################################################### 以上通用 ###################################################################################################################################################### 常用第三方模組的混淆選項 ####################################gson#如果用用到Gson解析包的,直接添加下面這幾行就能成功混淆,不然會報錯。-keepattributes Signature# Gson specific classes-keep class sun.misc.Unsafe { *; }# Application classes that will be serialized/deserialized over Gson-keep class com.google.gson.** { *; }-keep class com.google.gson.stream.** { *; }#mob-keep class android.net.http.SslError-keep class android.webkit.**{*;}-keep class cn.sharesdk.**{*;}-keep class com.sina.**{*;}-keep class m.framework.**{*;}-keep class **.R$* {*;}-keep class **.R{*;}-dontwarn cn.sharesdk.**-dontwarn **.R$*#butterknife-keep class butterknife.** { *; }-dontwarn butterknife.internal.**-keep class **$$ViewBinder { *; }-keepclasseswithmembernames class * { @butterknife.* <fields>;}-keepclasseswithmembernames class * { @butterknife.* <methods>;}######引用的其他Module可以直接在app的這個混淆檔案裡配置# 如果使用了Gson之類的工具要使被它解析的JavaBean類即實體類不被混淆。-keep class com.matrix.app.entity.json.** { *; }-keep class com.matrix.appsdk.network.model.** { *; }#####混淆保護自己項目的部分代碼以及引用的第三方jar包library########如果在當前的application module或者依賴的library module中使用了第三方的庫,並不需要顯式添加規則#-libraryjars xxx#添加了反而有可能在打包的時候遭遇同一個jar多次被指定的錯誤,一般只需要添加忽略警告和保持某些class不被混淆的聲明。#以libaray的形式引用了開源項目,如果不想混淆 keep 掉,在引入的module的build.gradle中設定minifyEnabled=false-keep class com.nineoldandroids.** { *; }-keep interface com.nineoldandroids.** { *; }-dontwarn com.nineoldandroids.**# 下拉重新整理-keep class in.srain.cube.** { *; }-keep interface in.srain.cube.** { *; }-dontwarn in.srain.cube.**# observablescrollview:tab fragment-keep class com.github.ksoichiro.** { *; }-keep interface com.github.ksoichiro.** { *; }-dontwarn com.github.ksoichiro.**
然後執行build的release打包,會在app目錄下產生一個proguard檔案夾,裡面有混淆前後檔案的映射資訊等文字檔,以後bug定位就靠它了:
AndroidStudio 混淆打包