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

简介: 1、错误描述 今天测试人员提了一个bug,说使用我们的app出现了闪退的bug,后来通过debug断点调试,发现我们的app转换服务器发送过来的json数据后,都是为null。

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 ;
}

-keepattributes Exceptions,InnerClasses,...
#过滤泛型
-keepattributes Signature
#过滤注解
-keepattributes *Annotation*
#过滤js
-keepattributes *JavascriptInterface*

# 保持 native 方法不被混淆
-keepclasseswithmembernames class * {
    native ;
}

# 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 (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);
}


 # 保持枚举 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 {
    (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 ;
#     public ;
#}
#
#-keep class com.umeng.message.* {
#    public ;
#     public ;
#}
#
#-keep class org.android.agoo.impl.* {
#    public ;
#     public ;
#}
#
#-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} 设置源文件中给定的字符串常量
  • 通配符匹配规则
    -这里写图片描述


  • 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"
                            }
                        }
                }
            }
        }
        ......
    }
}

更多关于混淆的相关内容的参考文章:

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

这里写图片描述

相关文章
|
1月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
1月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
26 1
|
1月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
18天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
1月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
18天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
42 14
|
21天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
19天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
31 5
|
18天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
|
19天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。

热门文章

最新文章