项目重构已经完成,使用了最新的retrofit框架,现在最后一步就是对代码进行混淆了。代码混淆使用了Proguard技术。
第一步:公共不混淆操作
########必须的progrud配置###### #指定代码的压缩级别 -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.** #保持 native 方法不被混淆 -keepclasseswithmembernames class * { native; } #保持自定义控件类不被混淆 -keepclasseswithmembers class * { public(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(android.content.Context); public(android.content.Context, android.util.AttributeSet); public(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; !private; !private; 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; } -keepclassmembers class fqcn.of.javascript.interface.for.webview { public *; } #避免混淆泛型 如果混淆报错建议关掉 -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 -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.** { *; } # 如果使用了Gson之类的工具要使被它解析的JavaBean类即实体类不被混淆。 -keep class com.guazi.power.model.entity.** { *; } #butterknife -keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.*; } -keepclasseswithmembernames class * { @butterknife.*; } # RxJava 0.21 -keep class rx.schedulers.Schedulers { public static; } -keep class rx.schedulers.ImmediateScheduler { public; } -keep class rx.schedulers.TestScheduler { public; } -keep class rx.schedulers.Schedulers { public static ** test(); } # Crashlytics 2.+ -keep class com.crashlytics.** { *; } -keep class com.crashlytics.android.** -keepattributes SourceFile, LineNumberTable, *Annotation* # fastjson -dontwarn com.alibaba.fastjson.** -keepattributes Signature -keepattributes *Annotation* #design -dontwarn android.support.design.** -keep class android.support.design.** { *; } -keep interface android.support.design.** { *; } -keep public class android.support.design.R$* { *; } #Glide -keep public class * implements com.bumptech.glide.module.GlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { **[] $VALUES; public *; } # OkHttp3 -dontwarn okhttp3.logging.** -keep class okhttp3.internal.**{*;} -dontwarn okio.** -dontwarn javax.annotation.Nullable -dontwarn javax.annotation.ParametersAreNonnullByDefault -keepattributes Signature -keepattributes *Annotation* -keep class okhttp3.** { *; } -keep interface okhttp3.** { *; } -dontwarn okhttp3.** # Retrofit -dontwarn retrofit2.** -keep class retrofit2.** { *; } -keepattributes Signature-keepattributes -keepattributes Exceptions # RxJava RxAndroid -dontwarn sun.misc.** -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { long producerIndex; long consumerIndex; } -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { rx.internal.util.atomic.LinkedQueueNode producerNode; } -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { rx.internal.util.atomic.LinkedQueueNode consumerNode; } #友盟统计 -keepclassmembers class * { public(org.json.JSONObject); } -keep public class [com.guazi.power].R$*{ public static final int *; } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } #百度地图 -keep class com.baidu.** {*;} -keep class vi.com.** {*;} -dontwarn com.baidu.** #小米推送 -keepclasseswithmembernames class com.xiaomi.**{*;} -keep public class * extends com.xiaomi.mipush.sdk.PushMessageReceiver #小米push keep包下的所有类 -keep class com.xiaomi.push.service.receivers.NetworkStatusReceiver {*;} -keep public class * extends android.content.BroadcastReceiver #可以防止一个误报的 warning 导致无法成功编译,如果编译使用的 Android 版本是 23。 -dontwarn com.xiaomi.push.** #小米push service #Warning:com.xiaomi.push.service.XMPushService: can't find referenced method 'void setLatestEventInfo(android.content.Context,java.lang.CharSequence,java.lang.CharSequence,android.app.PendingIntent)' in library class android.app.Notification -dontwarn org.apache.http.** -dontwarn android.net.http.AndroidHttpClient -dontwarn com.google.android.gms.** -dontwarn com.android.volley.toolbox.** #Warning:org.bouncycastle.jce.provider.X509LDAPCertStoreSpi: can't find referenced class javax.naming.NamingEnumeration -dontwarn javax.naming.** #自定义异常 -keep public class * extends java.lang.Exception #dagger -dontwarn dagger.internal.codegen.** -keepclassmembers,allowobfuscation class * { @javax.inject.* *; @dagger.* *;(); } -keep class dagger.* { *; } -keep class javax.inject.* { *; } -keep class * extends dagger.internal.Binding -keep class * extends dagger.internal.ModuleAdapter -keep class * extends dagger.internal.StaticInjection