美文网首页Android TipsAndroid 安卓技术分享android
proguard如何会导致json解析失效?

proguard如何会导致json解析失效?

作者: 腾儿飞 | 来源:发表于2017-03-31 23:59 被阅读435次

1. 楔子

json数据的解析是这个星球上99%的Android程序猿都会遇到的问题,而其中的大部分,都会使用Gson,故事就是从这里发生……

2. 一开始

通常json数据是从服务端取的,典型的一段json字符串如下:

  { "name": "老张","age": 18}

一般程序猿们会在本地写一个实体类与之对应,比如数据类Person:

public class Person { 
    private String name;
    private int age;
    //……省略中间get/set
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + '}';
    }
}

然后就可以愉快地使用Gson来进行解析啦,像这样:

Person someone = new Gson().fromJson(jsonString, Person.class);
Log.d("TAG", "someone: " + someone.toString());

一切顺利,程序猿们得到输出:

Person{ name='老张',age=18}

然后他们就愉快地下班去玩耍了。

3. 后来,他们开启了proguard

意外就是从这里开始的,开启了proguard之后,debug运行的程序一切如常,但是proguard之后输入的apk包,在安装之后的输出变成了这样:

Person{ name='null',age=0}

——解析出错了。
(算了,我编不下去了,从现在开始使用第一人称……)

4. 问题所在

经过反复排查,发现问题就是由proguard引起的。
我们知道,proguard的过程会执行压缩、混淆、去除无用代码等操作。而其中的混淆、去除无用代码的过程,对于使用了反射技术的代码来说,都是有可能受到影响的。
不幸的是:Gson.fromJson()就是基于反射来实现的。

通过反编译apk包,发现我们写的Person类,在没有被保护的情况下,会被proguard成类似这个样子的:


反编译代码1

可以看到,类名、字段名都改成了a/b这样的名字。
这样在使用Gson的时候,它尝试去序列化的字段就会变成了a/b,而不是之前的name/age了。
——那还反射个毛啊!

5. 解决

知道问题了,自然也就很好解决了。
方案是在proguard规则中,把Person类给保护起来

5.1 proguard文件编辑

proguard-rules.pro文件中添加规则(也可能是其他文件,具体见gradle文件中的定义),把数据类保护起来即可。
具体来说,可以直接保护当前类:

-keep class com.xxx.beans.Person {*;}

也可以保护整个包:

-keep class com.xxx.beans.* {*;}

还可以给Person添加一个对Serializable的实现,然后保护所有的Serializable

-keep class * implements java.io.Serializable {*; }

5.2 @Keep注解

另外,项目如果引用了注解支持库,那么给Person类加上@Keep的注解也可以防止它被混淆。

@Keep
public class Person {/*省略*/}

OK,加上保护之后,重新打包。
反编译这时的apk,可以看到,字段Person类没有再被混淆了:


反编译代码2

然后安装、运行,果然一切正常了。

Person{ name='老张',age=18}

完美。

6. 一些链接

反编译工具:https://github.com/google/android-classyshark
压缩代码和资源:https://developer.android.com/studio/build/shrink-code.html
proguard相关问题排查:https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/troubleshooting.html
关于作者:https://github.com/barryhappy

另外,希望这篇文章能对你有所帮助。
最近开始整了一个微信公众号,用以分享一些 Android 相关以及不相关的干货,既然都看到这里了,何不长按/扫码关注一下?
不只Android

不只Android

相关文章

  • proguard如何会导致json解析失效?

    1. 楔子 json数据的解析是这个星球上99%的Android程序猿都会遇到的问题,而其中的大部分,都会使用Gs...

  • proguard源码分析二 class字节码解析

    上一节我们分析了proguard的参数解析、配置获取、以及配置保存等等过程,本节我们继续分析proguard是如何...

  • 如何用Retrofit解析Json

    网上如何用Retrofit解析json的文章很多,但是很多都比较零散。比如如何解析复杂json格式?json格式里...

  • iOS-解析JSON(二)

    上一篇介绍了JSON以及本地JSON的解析,这一篇主要介绍如何解析从网络上获取的JSON数据 打印结果 JSON数...

  • 多线程网络-5

    Xmind ①发送请求拿到JSON数据后如何序列化(解析) ②如何把OC对象转换为JSON ③JSON数据和OC对...

  • Android开发中如何解析Json

    解析Json 有了请求,自然会有响应,那我们该如何解析服务端响应返回给我们的Json数据呢? 了解什么是Json ...

  • swift解析json

    由于使用网络接口隔段时间就可能失效了,我在这里就自己写个json。json格式的数据解析太常见了,话不多说直接码哈...

  • JSON

    JSON解析(反序列化) JSON解析(序列化) JSON解析补充

  • Json解析方式

    1.传统的JSON解析 1.1 生成Json 1.2 解析Json 2.Gson解析Json 2.1生成Json ...

  • ios 自定义导航按钮或自定义 push 动画,返回手势失效

    1自定义导航按钮 会导致返回手势失效2自定义push 动画同样会导致返回手势失效3自定义导航按钮同样会导致自定义 ...

网友评论

本文标题:proguard如何会导致json解析失效?

本文链接:https://www.haomeiwen.com/subject/pksvbttx.html