今天算是比较倒霉的一天,近视的我上班的时候眼镜没找到,看到要迟到了,也没找眼镜就直接飞奔到公司,看不到屏幕只能抱着屏幕撸码,我相信你们也能想到这画面,这不算什么,重点来了,在上班的时候改动了bean类中不管是上传的数据类还是从服务器中返回的数据都被我无意的混淆了 。导致我在获取数据的时候出现找不到这些数据,直接导致登录失败。这可要命了,知道导致的后果就是今天算白忙了。
还好我的leader是个对我们还可以,没说我什么但对我自己来说,这简直是要了我的命呀,怎么找错误都找不到,因为realse模式下是无法断点调试的,自以为聪明的我,直接把正式的地址放在测试中直接测试调试,这样的结果是没问题呀!登录正常,为什么在正式中就jj了呢?无法找到原因呀 ,各种逻辑都是没问题的,为什么会出现这样的问题呢,是在找不到错误的我只能找同事帮忙看下,在自己一筹莫展的时候,同事的一个提醒救了我一命呀,是不是把数据给混淆了 ,当我打开proguard-rules.pro文件的时候 灵光一现。有种领悟到绝世武功的感觉!不就是这个问题吗?我的个去,问题找到了,感觉我的同事呀。还真是混淆的问题,这里的bean是不能混淆的。
看到这,我似乎对混淆不够了解呀!不然的话也不会花这么长时间研究代码的逻辑而忽视了混淆过后对代码的影响。为此决定恶补下关于Android中的混淆相关的知识。
提到混淆,其实就是为了防止别人对你的代码进行反编译,可以完全了解你的代码。这些都是我们不应该犯的错误,为什么自己幸幸苦苦写的代码别人就可以轻而易举的获得。
废话不多讲直接上干货!
Android中有自己使用混淆的方法,在release模式下调用如下
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
如果我们有些不被混淆的可见库类成员使用的关键字
-dontskipnonpubliclibraryclassmembers
混淆后的类名为小写
-dontskipnonpubliclibraryclasses
#这句话能够使我们的项目混淆后产生映射文件 #包含有类名->混淆后类名的映射关系 ----
-verbose
#代码混淆压缩比,在0~7之间
-optimizationpasses 7
#抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
#避免混淆泛型
-keepattributes Signature
#Android在默认的情况下会删除一些包 使用-dontshrink 可以禁止这样的情况发生
#不进行混淆,默认开启混淆。除-keep指定的类及成员外,都会被替换成简短、随机的、
名称,以达到混淆的目的。-dontobfuscate
#指定不对class进行预校验,默认情况下,在编译版本为micro或者1.6或更高版本时是开启的。但编译成Android版本时,预校验是不必须的,配置这个选项可以节省一点编译时间。
-preverify
-dontshrink
-dontpreverify
-dontoptimize
-dontusemixedcaseclassnames
-flattenpackagehierarchy
-allowaccessmodification
-printmapping map.txt
-optimizationpasses 7
-verbose
-keepattributes Exceptions,InnerClasses
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-ignorewarnings
这样就可以混淆我们的代码了,但有些像数据实体类我们是不希望混淆代码的该怎么办呢,,使用-keep就可以了,比如在我们项目中我们要对fragment,activity,service等这些类不被混淆,显示如下。
-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 java.lang.Throwable {*;}
-keep public class * extends java.lang.Exception {*;}
#保持 Serializable 不被混淆
-keepnames class * implements java.io.Serializable
其他类似
如果我要对实体类进行混淆呢?其实也一样但要把你实体类对应的文件路径加上,重要的事情说三遍这里的路径一定要写对。路径!。路径!。路径!。我就是上面的路径问题一直找不到问题的说在 所以在一切都正常的情况下,一定要检查混淆。在没有混淆的地方一定要看路径是否正确。好了说了这么多怎么配置不被混淆的实体类路径呢?这里的路径就是你的java文件到bean的包结构
-keep class 路径.bean.** { *; }
我们的资源文件在编译的时候会产生R文件,R文件也不要被混淆,如下配置
-keep public class [包名].R$*{ public static final int *;}
有的时候我们使用的注解也不希望被混淆
-keepattributes Signature
-keepattributes *Annotation*
有时候我们会引用native方法,我们不希望native方法被混淆 ,还有就是你自定义控件也不希望有些方法被混淆。防止类中的方法被混淆的关键字 -keepclasseswithmembernames
-keepclasseswithmembernames class * { native <methods>; }
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
有的时候我们不希望有些类中的变量被混淆 使用的关键字是 -keepclassmembers 结合我们的项目,这里有一个枚举类做个例子
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
指定属性不被混淆,这里的属性可以是多个并用,隔开
-keepattributes SourceFile,LineNumberTable
设置源文件中给定的资源文件常量
-renamesourcefileattribute SourceFile
不提示警告的关键字 -dontwarn 和忽视警告的关键字 -ignorewarnings
混淆差不多就这么多了。祝大家周末愉快 !!!
网友评论