总结下 在Android Studio下作代码混淆碰到的一些问题, 以及解决方法,其实就是总结下别人的经验
一般流程:
1.首先开启签名混淆, 在module中的build.gradle中:
buildTypes {
release {
minifyEnabled true //开启混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
2. 然后在module的目录下找到proguard-rules.pro, 没有就自己建一个,
在这里增加混淆规则, 先加上一些通用的规则:
-optimizationpasses 5 # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-dontskipnonpubliclibraryclasses
-keepattributes SourceFile,LineNumberTable
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法
-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 # 保持哪些类不被混淆
-keepclasseswithmembernames class * { # 保持 native 方法不被混淆
native ;
}
-keepclasseswithmembers class * { # 保持自定义控件类不被混淆
public (android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定义控件类不被混淆
public (android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆
public void *(android.view.View);
}
-keepclassmembers enum * { # 保持枚举 enum 类不被混淆
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆
public static final android.os.Parcelable$Creator *;
}
#如果引用了v4或者v7包
-dontwarn android.support.**
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment
如果使用了支付宝,
#支付宝
-dontwarn com.alipay.**
-keep class com.alipay.**{*;}
-dontwarn com.ta.utdid2.**
-keep class com.ta.utdid2.**{*;}
-dontwarn com.ut.device.**
-keep class com.ut.device.**{*;}
如果加了友盟:
#友盟
-keep class com.umeng.**{*;}
如果使用了百度地图:
-dontwarn com.baidu.**
-keep class com.baidu.**{*;}
如果使用 nineoldandrois包
-dontwarn com.nineoldandroids.**
-keep class com.nineoldandroids.**{*;}
如果使用了银联的
-dontwarn com.unionpay.**
-keep class com.unionpay.**{*;}
如果使用了xutils:
-dontwarn com.lidroid.xutils.**
-keep class com.lidroid.xutils.**{*;}
如果使用了gson:
-dontwarn com.google.gson.**
-keep class com.google.gson.**{*;}
-keep class sun.misc.Unsafe {*;}
其他的引用到的第三方包大致上要添加取消混淆都类似上面的
问题:
1.===================================================================
, 因为xutils使用了apache的东西, 如果在
compileSdkVersion 23
则,需要单独导入apache的东西,因为Android M版本删除掉了apache的联网包
在module的build.gradle中增加依赖
dependencies {
compile 'org.apache.httpcomponents:httpcore:4.4.2'
}
android {
useLibrary 'org.apache.http.legacy'
}
使用 useLibrary 需要在project的 build.gradle中设置gradle版本为1.3.0以上,否则gradle会爆找不到方法的错
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
}
然后在混淆规则中增加
-dontwarn org.apache.http.**
-keep class org.apache.http.**{*;}
2.===================================================================
然后, 有些第三方包已经开始支持android M了 , 所以会爆一个错,类似于这样
Warning: u.aly.bt: can't find referenced method 'int checkSelfPermission(java.lang.String)' in library class android.content.Context
Warning: there were 1 unresolved references to library class members.
因为调用了api 23的方法checkSelfPermission() , 都说要将 本地编译环境设置成这样,
compileSdkVersion 23
则,相应的其他的一些也要设置成 api23 的环境,如
buildToolsVersion "23.0.1"
以及
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:appcompat-v7:23.1.1'
只是保留了
targetSdkVersion 22
,则可以不用管 android M新的 运行时权限问题了,
关于targetSdkVersion 相关的信息,可以参考
貌似运行时权限问题也有开源库解决方案了,也没去搜
[2016/8/19更新]
最近生成aar包,提供给第三方使用,aar包应用了混淆,同时提供的接口需要暴露不能混淆,
如下是配置内容:
#SDK对外提供的调用不混淆
-dontwarn cn.f.a.m.SDKTools
-keep class cn.f.a.m.SDKTools
-keepclassmembers class cn.f.a.m.SDKTools{
public static ** getInstance(); //指定的静态方法不混淆
public void req*(...); //指定的方法名前缀为“req”的public方法不混淆,方法参数不确定多少个用“...”
public static final ; //指定的所有的static final 的类属性不混淆
}