我的Android进阶之旅------>解决Jackson等第三方转换Json的开发包在开启混淆后转换的实体类数据都是null的bug

来源:互联网 发布:mac mysql dmg 安装 编辑:程序博客网 时间:2024/05/01 17:39

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

作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng

这里写图片描述

1 0
原创粉丝点击