【Android】Android Studio使用gradle匯出jar包並混淆程式碼
阿新 • • 發佈:2019-01-23
整理下最近工作中混淆程式碼時遇到的問題,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 保護類的成員以免重寫的方法被混淆不能正確的呼叫