안드로이드에서 GSON 직렬화된 객체를 사용할 때 필드가 최적화되는 문제에 대한 솔루션


1. 문제 설명

다음과 같은 구조를 가지고 있습니다:

public class NativeParam<T> {

    private T data;

    public NativeParam(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
};

NativeParam<String> data = "1.0.1";
String result = gson.toJson(new NativeParam<>("1.0.1"));
log.i(TAG,"GET_APP_VERSION_INFO-result:" + result);
});

출력 정보는 다음과 같습니다.

GET_APP_VERSION_INFO-result:{"a":"1.0.1"}

위에 표시된 대로 "data" 필드는 "a"로 직렬화됩니다.


2. 문제 해결 과정 및 원인 분석


처음에는 필드가 "a", "b" 등으로 최적화되어 있다고 생각했습니다. 이는 Gson 라이브러리가 기본적으로 필드 난독화(필드 이름 지정 정책) 기능을 활성화하여 필드 이름을 더 짧은 형식으로 압축하기 때문일 수 있습니다.


해결하려면 다음 두 가지 방법을 시도해 보십시오.


1. 필드 난독화 비활성화

Gson의 필드 명명 정책을 설정하여 필드 난독화를 비활성화합니다. 클래스를 사용하여 GsonBuilderGson 개체를 만들고 setFieldNamingPolicy메서드를 호출하여 필드 명명 전략을 설정할 수 있습니다. 필드 난독화를 비활성화하는 샘플 코드는 다음과 같습니다.

Gson gson = new GsonBuilder()
        .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
        .create();

String jsonString = gson.toJson(yourObject);

필드 이름 지정 전략으로 사용하면 FieldNamingPolicy.IDENTITY필드 이름이 원래 개체의 필드 이름과 일관성을 유지하고 압축되지 않습니다.


2. @SerializedName주석을 사용하세요

특정 필드에 대해서만 필드 난독화를 비활성화하려면 해당 필드에 주석을 사용 @SerializedName하고 주석 값에 원래 필드 이름을 지정하면 됩니다.


다음과 같이:

class YourClass {
    @SerializedName("originalFieldName")
    private String fieldName;
    // ...
}

Gson gson = new Gson();
String jsonString = gson.toJson(yourObject);

필드에 대한 주석을 사용하면 @SerializedName필드 난독화의 영향을 받지 않고 JSON 문자열로 직렬화될 때 필드가 사용해야 하는 원래 필드 이름을 지정할 수 있습니다.


그러나 위의 두 가지 방법으로는 문제를 해결하지 못했습니다.

갑자기 "a"와 "b"로 최적화되는 것은 패키징 중에 코드 난독화를 켜는 것과 비슷하다고 생각하여 과감히 gson의 난독화 규칙을 추가했고 문제가 해결되었습니다.


3. 최종 솔루션

gson의 난독화 규칙 외에도 참고: com.test.demo.NativeParam을 사용자 고유의 모드 구조로 바꿔야 합니다.


#gson  start
# custom 不能混淆的要加上
# Application classes that will be serialized/deserialized over Gson
-keep class com.test.demo.NativeParam {  *; }

#gson start
-keep class com.google.gson.** {*;}
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
-keep class com.google.** {
    <fields>;
    <methods>;
}
-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();
}
-dontwarn com.google.gson.**
#gson  end

테스트 출력 결과는 다음과 같습니다.

GET_APP_VERSION_INFO-result:{"data":"1.0.1"}

Supongo que te gusta

Origin blog.csdn.net/lizhong2008/article/details/135140711
Recomendado
Clasificación