我的Android进阶之旅------>解决Jackson等第三方转换Json的开发包在开启混淆后转换的实体类数据都是null的bug
2016-04-28 20:25
746 查看
1、错误描述
今天测试人员提了一个bug,说使用我们的app出现了闪退的bug,后来通过debug断点调试,发现我们的app转换服务器发送过来的json数据后,都是为null。而之前已经提测快一个月的功能,一直都是稳定的,为什么现在会报java.lang.NullPointerException。2、错误原因
原来我提测了一个月的APP版本一直没有打开混淆开关,而出问题的这个APP版本在即将要发布出去的时候打开了混淆开关。这样的话,我那些要通过转换json数据为bean实体类,因为没有在proguard-rules.pro混淆文件声明不混淆,而导致json转换的时候,转换后的数据都是为nulll。3、解决方法
在proguard-rules.pro混淆文件中所有jackson对应实体类都要声明不能混淆例如:
#所有jackson对应实体类不能混淆 -keep class com.oyp.model.** {*;}
4、注意事项
只要是Json数据转换后的实体类,都要在混淆文件中保持不混淆否则开启混淆后,转换后的数据都会为null,这个坑稍不注意的话会跌得很惨!
5、部分混淆文件
# 指定代码的压缩级别 #-optimizationpasses 5 # 混淆时是否记录日志 -verbose -dontpreverify # 不预校验 -dontoptimize #不优化输入的类文件 -dontshrink #该选项 表示 不启用压缩 -dontusemixedcaseclassnames # 混淆时不会产生形形色色的类名 -dontskipnonpubliclibraryclasses #不跳过(混淆) jars中的 非public classes 默认选项 #-dontwarn # 去掉警告 #-dontskipnonpubliclibraryclassmembers #不跳过 jars中的非public classes的members # 优化 #-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #-allowaccessmodification #优化时允许访问并修改有修饰符的类和类的成员 #-renamesourcefileattribute SourceFile #-keepattributes SourceFile,LineNumberTable #-repackageclasses '' -keepclassmembers class **.R$* { public static <fields>; } -keepattributes Exceptions,InnerClasses,... #过滤泛型 -keepattributes Signature #过滤注解 -keepattributes *Annotation* #过滤js -keepattributes *JavascriptInterface* # 保持 native 方法不被混淆 -keepclasseswithmembernames class * { native <methods>; } # keep setters in Views so that animations can still work. # see http://proguard.sourceforge.net/manual/examples.html#beans -keepclassmembers public class * extends android.view.View { void set*(***); *** get*(); } # 保持自定义控件类不被混淆 #-keepclasseswithmembers class * { # public <init>(android.content.Context, android.util.AttributeSet); #} #-keepclasseswithmembers class * { # public <init>(android.content.Context, android.util.AttributeSet, int); #} -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } # 保持枚举 enum 类不被混淆 -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } # 保持 Parcelable 不被混淆 -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } #-keep public class * { # public protected *; #} -keep public class * implements java.io.Serializable { public *; } -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); } -keep class sun.misc.Unsafe { *; } -dontwarn com.amap.api.** -dontwarn com.a.a.** -dontwarn com.autonavi.** -dontwarn org.apache.http.** -dontwarn com.fasterxml.jackson.databind.** -dontwarn com.google.zxing.client.android.** -dontwarn com.tencent.weibo.sdk.android.** -dontwarn com.bbk.secureunisignon.** -dontwarn com.qiniu.android.** -dontwarn com.umeng.socialize.** -dontwarn net.sf.json.** -keep class com.amap.api.** {*;} -keep class com.autonavi.** {*;} -keep class com.a.a.** {*;} -keep class android.support.** {*;} -keep class org.** {*;} -keep class com.fasterxml.jackson.core.** {*;} -keep interface com.fasterxml.jackson.core { *; } -keep public class * extends com.fasterxml.jackson.core.** -keep class com.fasterxml.jackson.databind.introspect.VisibilityChecker$Std.<clinit> -keep class com.fasterxml.jackson.databind.ObjectMapper.<clinit> -keep class com.fasterxml.jackson.databind.** {*;} -keep class com.fasterxml.jackson.databind.introspect.VisibilityChecker$*{*;} -keep interface com.fasterxml.jackson.databind { *; } -keep public class * extends com.fasterxml.jackson.databind.** -keep class net.sf.json.** {*;} -keep class com.qiniu.android.** {*;} -keep class com.bbk.secureunisignon.** {*;} -keep class com.tencent.weibo.sdk.android.** {*;} -keep class com.umeng.socialize.** {*;} -keep class com.google.zxing.client.android.** {*;} -keep class com.j256.ormlite.** {*;} -keep class com.org.simple.eventbus.**{*;} -keep class com.android.**{*;} #-assumenosideeffects class_specification # 下面两条为EventBus -keepclassmembers class ** { public void onEvent*(**); } # Only required if you use AsyncExecutor -keepclassmembers class * extends de.greenrobot.event.util.ThrowableFailureEvent { <init>(java.lang.Throwable); } # for squareup picasso -dontwarn com.squareup.okhttp.** # for butterknife -dontwarn butterknife.internal.** -keep class **$$ViewInjector { *; } -keepnames class * { @butterknife.InjectView *;} #所有jackson对应实体类不能混淆 -keep class com.oyp.model.** {*;} -keep class com.oyp.dao.**{*;} -keep class com.oyp.net.bean.** {*;} -keep class com.oyp.entity.**{*;} -keep class com.oyp.service.location.PushBean{*;} -keep class com.oyp.service.umeng.UmengShareInfo{*;} -keep class com.oyp.service.umeng.UmengShareInfoKV{*;} ##友盟推送混淆 -dontwarn com.umeng.message.proguard.** #-dontwarn com.ut.mini.** -dontwarn okio.** #-dontwarn com.xiaomi.** #-dontwarn com.squareup.wire.** #-dontwarn android.support.v4.** # #-keepattributes *Annotation* # #-keep class android.support.v4.** { *; } #-keep interface android.support.v4.app.** { *; } # -keep class okio.** {*;} #-keep class com.squareup.wire.** {*;} # #-keep class com.umeng.message.protobuffer.* { # public <fields>; # public <methods>; #} # #-keep class com.umeng.message.* { # public <fields>; # public <methods>; #} # #-keep class org.android.agoo.impl.* { # public <fields>; # public <methods>; #} # #-keep class org.android.agoo.service.* {*;} # #-keep class org.android.spdy.**{*;} # #-keep public class com.oyp.R$*{ # public static final int *; #}
6、混淆知识点
保留-keep {Modifier} {class_specification} 保护指定的类文件和类的成员 -keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好 -keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。 -keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除) -keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除) -keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后) -printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
压缩
-dontshrink 不压缩输入的类文件 -printusage {filename} -whyareyoukeeping {class_specification}
优化
-dontoptimize 不优化输入的类文件 -assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用 -allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
混淆
-dontobfuscate 不混淆输入的类文件 -obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称 -overloadaggressively 混淆时应用侵入式重载 -useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆 -flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中 -repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中 -dontusemixedcaseclassnames 混淆时不会产生形形色色的类名 -keepattributes {attribute_name,…} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses. -renamesourcefileattribute {string} 设置源文件中给定的字符串常量
通配符匹配规则
-
更详细的语法请戳:http://proguard.sourceforge.net/manual/usage.html#classspecification
ProGuard的输出文件说明
混淆后,会在/build/proguard/目录下输出下面的文件
dump.txt 描述apk文件中所有类文件间的内部结构。
mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。
seeds.txt 列出了未被混淆的类和成员
usage.txt 列出了从apk中删除的代码
当我们需要处理crash log的时候,就可以通过mapping.txt的映射关系找到对应的类,方法,字段等。方法如下:
sdk\tools\proguard\bin 目录下有个retrace工具可以将混淆后的报错堆栈解码成正常的类名
window下为retrace.bat,linux和mac为retrace.sh,
使用方法如下:
1、 将crash log保存为yourfilename.txt
2、 拿到版本发布时生成的mapping.txt
3、 执行命令retrace.bat -verbose mapping.txt yourfilename.txt
所以我们每次打包版本都需要保存最新的mapping.txt文件。如果要使用到第三方的crash统计平台,比如bugly,还需要我们上传APP版本对应的mapping.txt.每次都要保存最新的mapping文件,那不就很麻烦?放心,gradle会帮到你,只需要在bulid.gradle加入下面的一句。每次我们编译的时候,都会自动帮你保存mapping文件到本地的。
android { applicationVariants.all { variant -> variant.outputs.each { output -> if (variant.getBuildType().isMinifyEnabled()) { variant.assemble.doLast{ copy { from variant.mappingFile into "${projectDir}/mappings" rename { String fileName -> "mapping-${variant.name}.txt" } } } } } ...... } }
更多关于混淆的相关内容的参考文章:
使用proguard混淆android代码http://www.jianshu.com/p/0202845db617
Android ProGuard 混淆 详解
http://blog.csdn.net/chen930724/article/details/49687067
http://bbs.51cto.com/thread-1084158-1-1.html
android 代码 混淆- 原来如此简单
http://www.cnblogs.com/0616–ataozhijia/p/3727310.html
http://blog.csdn.net/fhl13017599952/article/details/24265831
使用proguard混淆android代码
http://my.oschina.net/sammy1990/blog/271306
Android分享:代码混淆那些事
https://segmentfault.com/a/1190000004461614
Proguard Square文档
https://www.guardsquare.com/en/proguard
Proguard Square常见错误文档
https://www.guardsquare.com/en/proguard/manual/troubleshooting
【我的Android进阶之旅】Android 混淆文件资源分类整理
http://blog.csdn.net/ouyang_peng/article/details/73088090
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
相关文章推荐
- android.textiview.settextcolor失效的问题
- 关于 Fiddler 出现Response is encoded and may need to be decoded before inspection.
- Android scrollTo()与scrollBy()的区别
- Android中Parcelable接口用法
- android获取周围WIFI热点
- 彻底解决Android 应用方法数不能超过65536的问题
- android USB触摸屏是滑鼠模状态问题
- Android 主题资源风格定制 <1>
- Android 适配不同分辨率屏幕
- Android本地数据的存储和读取(文件格式)
- 服务&广播与服务day2(66期第八天)
- android学习之4中引用
- Android开发笔记之:深入理解Cursor相关的性能问题
- Android 解决android imeoptions 失效的问题
- Android中使用多张图片组成动画 AnimationDrawable
- Android Studio教程从入门到精通
- Android手机开启开发者模式
- Android相机开发中遇到的一些问题
- Android——Intent 相关
- Android6.0 运行时权限