混淆小结
最近公司项目在做全量混淆的功能,做好了打包一测 发现一个比较有意思的地方————混淆引起的问题
异常现象
在项目中有个我的黄金页面 里面有个实时金价的显示,这个270.84元/克 的显示 是一个定时查询接口返回的数据,默认是5S刷新一次,服务端会返回这个具体的刷新时间,但是现在发现这个控件一直显示0,而且这个文案加了一个上滑更新的效果 ,看到的效果就是一个一直在抖动的东西。
问题的追溯
下载一个线上环境发现 没任何问题,然后打了一个混淆的测试包,发现一样的现象,因为没法断点调试,所以在里面打印日志排查,项目中使用的handler发消息
public class GoldFreshHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
request();
if(checkActiveListener()>0) {
android.util.Log.e("GoldProvider d的handler ", "GOLD_UPDATE_DURATION "+GOLD_UPDATE_DURATION );
mHandler.sendEmptyMessageDelayed(ACTION_GOLD_REQUEST, GOLD_UPDATE_DURATION);
}
}
}
发现在上面的地方这个 GOLD_UPDATE_DURATION 一直为0,使用抓包工具一看:
image.png
发现这有数据啊,然后在网络请求回调的地方去吧data.toString()打出来 发现数据都是默认值 就是int double 是0 string类型的是空
处理问题
现在就直接定位到问题是打包混淆把这个javaBean对象混淆了,虽然没有报错,但是在解析这种序列化 和反序列化的时候数据出问题了,
反编译看到,这个包里面确实被混淆了
image.png
现在在混淆文件中,也就是 proguard-project.txt 中增加了:
-keep class com.xiaoniu.finance.interfaces.**{*;}
完美解决了数据显示问题,而且反编译也没有被混淆:
还有一种方案就是看这个混淆文件注释中给我们提供了:
-keep class * implements java.io.Serializable {*;}
这个和上面的区别在于这个混淆了接口中的东西,只是实现这个序列化的没有被混淆
image.png
知识点总结
keep 保留类和类中的成员,防止被混淆或者移除
keepnames 保留类和类中的成员,防止被混淆,但是当成员没有被引用时会被移除
keepclassmembers 只保留类中的成员,防止他们被混淆或者移除
keepclassmembersnames 只保留类中的成员,防止他们被混淆或者移除,但是当类中的成员没有被引用时还是会被移除
keepclasseswithmembers 保留类和类中的成员,前提是指明的类中必须含有该成员,没有的话还是会被混淆
keepclasseswithmembersnames 保留类和类中的成员,前提是指明的类中必须含有该成员,没有的话还是会被混淆。需要注意的是没有被引用的成员会被移除
1.不混淆某个类的构造函数
例如不混淆Test类的构造函数
-keepcalssmembers clsss com.ticktick.example.Text{
public <init>(int,int)
}
2.不混淆某个包下所有的类或者指定的类
例如不混淆package com.ticktick.example下的所有的类/接口
不混淆这个包下的所有的类
-keep class com.ticktick.example.**{*;}
例如不混淆com.ticktick.example.Text类
-keep class com.ticktick.example.Text{*;}
如果希望不混淆某个接口,则把上述命令的class替换为interface即可.
3.不混淆某个类的特定的函数
例如不混淆com.ticktick.example.Test类中的setTestString函数
-keepclassmembers class com.ticktick.example.Test{
public void setTestString(java.lang.String);
}
4.不混淆某个类的子类,某个接口的实现
例如不混淆com.ticktick.example.Test的子类
-keep public class * extend com.ticktick.example.Test
例如不混淆com.ticktick.example.TestInterface的实现
-keep class * implements com.ticktick.example.TestInterface{
public static final com.ticktick.example.TestInterface$Creator *;
}
5.注意第三方依赖包
例如添加android-support-v4.jar依赖包
-libraryjars libs/android-support-v4.jar
-dontwarn android.support.v4.**{*;}
-keep class android.support.v4.**{*;}
-keep interface android.support.v4.**{*;}
注意添加dontwarn,因为默认情况下proguard会检查每一个引用是否正确,但是第三方库里往往有些不会用到的类,没有正确引用,所有如果不配置的话,系统会报错.
网友评论