1. 程式人生 > >【Android】Android Studio使用gradle匯出jar包並混淆程式碼

【Android】Android Studio使用gradle匯出jar包並混淆程式碼

整理下最近工作中混淆程式碼時遇到的問題,gradle混淆指令碼Android Studio 使用 Gradle 打包 Jar感謝這位博主。
打jar包

task makeJar(dependsOn: ['compileReleaseJavaWithJavac'], type: Jar) {
    appendix = "demo"
    baseName = "androidJar"
    version = "1.0.0"
    classifier = "release"
    //字尾名
    extension = "jar"
    //最終的 Jar 包名,如果沒設定,預設為 [baseName]-[appendix]-[version]-[classifier].[extension]
archiveName = "DydGameSDKLib.jar" //需打包的資源所在的路徑集 def srcClassDir = [project.buildDir.absolutePath + "/intermediates/classes/release"]; //初始化資源路徑集 from srcClassDir //去除路徑集下部分的資源 exclude "com/yourPackegeName/game/BuildConfig.class" exclude "**/R.class" exclude "**/R\$*.class" //只匯入資源路徑集下的部分資源
include "com/yourPackegeName/**/*.class" }

匯出混淆包

task proguardJar(dependsOn: ['makeJar'], type: ProGuardTask) {
    //Android 預設的 proguard 檔案
    configuration android.getDefaultProguardFile('proguard-android.txt')
    //manifest 註冊的元件對應的 proguard 檔案
    configuration 'proguard-rules.pro'
    String
inJar = makeJar.archivePath.getAbsolutePath() //輸入 jar injars inJar //輸出 jar outjars inJar.substring(0, inJar.lastIndexOf(File.separator)) + "/proguard-${makeJar.archiveName}" //設定不刪除未引用的資源(類,方法等) dontshrink Plugin plugin = getPlugins().hasPlugin(AppPlugin) ? getPlugins().findPlugin(AppPlugin) : getPlugins().findPlugin(LibraryPlugin) if (plugin != null) { List<String> runtimeJarList if (plugin.getMetaClass().getMetaMethod("getRuntimeJarList")) { runtimeJarList = plugin.getRuntimeJarList() } else if (android.getMetaClass().getMetaMethod("getBootClasspath")) { runtimeJarList = android.getBootClasspath() } else { runtimeJarList = plugin.getBootClasspath() } for (String runtimeJar : runtimeJarList) { //給 proguard 新增 runtime libraryjars(runtimeJar) } } }

混淆檔案proguard-android.txt

  -keep class com.yourPackegeName.aidl.** { *;}
    -keep class com.yourPackegeName.game.activity.** { *;}
    -keepattributes Exceptions,InnerClasses
    -keep class com.yourPackegeName.game.api.* { *;}
    -keepclassmembers class com.yourPackegeName.game.api.** { *;}
    -keep class com.yourPackegeName.game.callback.** { *;}
    -keep class com.yourPackegeName.game.entity.** { *;}
    -keepclassmembers class com.yourPackegeName.game.dialog.AvatarImageListener{*;}
    -keepclassmembers class com.yourPackegeName.game.network.DydErrorListener{*;}
    -keepclassmembers class com.yourPackegeName.game.network.SuccessListener{*;}
    -keepclassmembers class com.yourPackegeName.game.network.model.*{*;}

     -keepclassmembers class com.yourPackegeName.game.network.util.DydOkHttpNetwork{ *;}
     -keepclassmembers class com.yourPackegeName.game.network.util.DydStringRequest{ *;}
     -keepclassmembers class com.yourPackegeName.game.network.util.OkHttpStack{ *;}
     -keepclassmembers class com.yourPackegeName.game.network.util.DydImageCatch{ *;}


    -keepattributes Signature
    -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* ();
    }
    -dontwarn  com.android.volley.**
    -dontwarn com.alibaba.fastjson.**
    -dontwarn  android.support.v4.**
    -dontwarn  org.apache.**
    -dontwarn com.pingplusplus.**
    -dontwarn okio.**
    -dontwarn com.squareup.**
    -dontwarn android.webkit.**
    -dontwarn com.yourPackegeName.**
    -dontwarn android.**
    -dontwarn com.ta.utdid2.**

引數解釋

-keep {Modifier} {class_specification}    保護指定的類檔案和類的成員   
-keepclassmembers {modifier} {class_specification}保護指定類的成員,如果此類受到保護他們會保護的更好  
-dontwarn 忽略警告

-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* ();
    }
    忽略自定義view
    -keepattributes Signature忽略泛型
    -keepattributes Exceptions,InnerClasses忽略異常和內部類

問題記錄
1.java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
一般是混淆的時候泛型沒有被保留導致class cast時出錯
解決:-keepattributes Signature
2.內部類找不到
解決:

-keepattributes Exceptions,InnerClasses
也可以A$*表示保留所有內部類
-keep class com.xxx.A
-keep class com.xxx.A$*
只保留某一個內部類
-keep class com.xxx.A
-keep class com.xxx.A$B

3.混淆過程中引用的包丟擲warning導致混淆失敗
解決:-dontwarn com.alibaba.fastjson.** 告訴編譯器不要提示這個包的警告

4.java.lang.AbstractMethodError: abstract method not implemented,這種錯誤是因為使用匿名內部類時,類的實現方法被混淆,導致找不到具體的實現方法例如有個類或者介面

A{ a()}
A a = new A(){
a(){
.......
}
}

解決辦法:將匿名內部類提出到內部類或者一個新的類再混淆,暫時沒找到其他辦法
5.如果有類繼承或者實現其他的類/介面,使用-keepclassmembers class 保護類的成員以免重寫的方法被混淆不能正確的呼叫