场景
项目用gson框架。配并开混淆后,release版运行某处失败。
日志
2019-11-02 11:29:43.242 4900-4900/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.lalala.lalala, PID: 4900
java.lang.NullPointerException: throw with null exception
at module.login.bean.UserBean$a.a(Unknown Source:3)
at module.login.LoginActivity.a(SourceFile:25)
at j.c.a.a(Unknown Source:8)
at d.g.a.y.i.c(SourceFile:2)
at d.g.a.y.i.b(SourceFile:10)
at d.g.a.y.i.a(SourceFile:13)
at d.g.b.o$a.run(SourceFile:6)
at d.g.a.e$l.run(SourceFile:6)
at android.os.Handler.handleCallback(Handler.java:891)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:7539)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)
分析
混淆后映射错。
解决
接口
package base;
import androidx.annotation.Keep;
/**
* Created on 2019/11/2.
*
* @author 郑少鹏
* @desc BaseGsonBean
*/
@Keep
public interface BaseGsonBean {
}
实体类
package module.login.bean;
import base.BaseGsonBean;
/**
* Created on 2019/4/24.
*
* @author 郑少鹏
* @desc 用户
*/
public class UserBean implements BaseGsonBean {
/**
* data : {"userId":4,
* "number":null,
* "mobile":"13673541527",
* "token":"ey",
* "gender":"male",
* "name":"哈哈",
* "birthDay":"2019-05-05",
* "pharmacy":"西安北关正街店"}
* meta : {"code":2000,"message":"登录成功"}
*/
private DataBean data;
private MetaBean meta;
public DataBean getData() {
return data;
}
public void setData(DataBean data) {
this.data = data;
}
public MetaBean getMeta() {
return meta;
}
public void setMeta(MetaBean meta) {
this.meta = meta;
}
public static class DataBean implements BaseGsonBean {
/**
* userId : 4
* number : null
* mobile : 13673541527
* token : ey
* gender : male
* name : 哈哈
* birthDay : 2019-05-05
* pharmacy : 西安北关正街店
*/
private int userId;
private String number;
private String mobile;
private String token;
private String gender;
private String name;
private String birthDay;
private String pharmacy;
public int getUserId() {
return userId;
}
public String getNumber() {
return number;
}
public String getMobile() {
return mobile;
}
public String getToken() {
return token;
}
public String getGender() {
return gender;
}
public String getName() {
return name;
}
public String getBirthDay() {
return birthDay;
}
public String getPharmacy() {
return pharmacy;
}
}
public static class MetaBean implements BaseGsonBean {
/**
* code : 2000
* message : 登录成功
*/
private int code;
private String message;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
}
proguard-rules.pro
#【gson】
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
#-keep class com.google.gson.examples.android.model.** { <fields>; }
# 谷歌示例(如下替换)
-keep class * implements base.BaseGsonBean {*;}
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}