每天記錄學習的新知識 :Gson之TypeAdapterFactory

參考地址

參考地址:Android端使用Retrofit實現與RestAPI後臺進行數據交互

TypeAdapterFactory

Gson中我們知道通過TypeAdapter可以修改序列化和反序列化的操作,而TypeAdapter的原理是最後封裝成爲TypeAdapterFactory使用,所以呢我們能不能直接自定義TypeAdapterFactory以實現序列化和反序列化呢?答案是可以的。

可以看到TypeAdapterFactory內部也實現了自己的TypeAdapter。

public class CustomTypeAdapterFactory implements TypeAdapterFactory {
    
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        return null;//這裏需要自定義TypeAdapter
    }

}

自定義TypeAdapterFactory

參考地址:Android端使用Retrofit實現與RestAPI後臺進行數據交互

    public static final String ERROR_CODE = "ERROR_CODE ";
    public static final String ERROR_CODE_SUCCESS = "ERROR_CODE_SUCCESS";
    public static final String RESULT = "RESULT ";
    public static final String ERROR_MSG = "ERROR_MSG ";
    public static final String SEPARATOR = "&#-SEPARATOR-#&";
public class ResponseTypeAdapterFactory implements TypeAdapterFactory {

    ResponseTypeAdapterFactory() {
    }

    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {

        final TypeAdapter<T> delegateAdapter = gson.getDelegateAdapter(this, type);
        final TypeAdapter<JsonElement> jsonElementAdapter = gson.getAdapter(JsonElement.class);

        return new TypeAdapter<T>() {

            @Override
            public void write(JsonWriter out, T value) throws IOException {
                delegateAdapter.write(out, value);
            }

            @Override
            public T read(JsonReader in) throws IOException {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return null;
                }
                JsonElement jsonElement = jsonElementAdapter.read(in);
                if (jsonElement.isJsonObject()) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    if (jsonObject.has(ERROR_CODE) && jsonObject.has(ERROR_MSG)) {
                        if (jsonObject.get(ERROR_CODE).getAsString().equals(ERROR_CODE_SUCCESS)) {
                            if (jsonObject.has(RESULT)) {
                                if (jsonObject.get(RESULT).isJsonNull()) {
                                    return delegateAdapter.fromJsonTree(new JsonObject());
                                }
                                return delegateAdapter.fromJsonTree(jsonObject.get(RESULT));
                            } else {
                                return delegateAdapter.fromJsonTree(new JsonObject());
                            }
                        } else {
                            throw new IOException(jsonObject.get(ERROR_CODE).getAsString() + SEPARATOR + jsonObject.get(ERROR_MSG).getAsString());
                        }
                    }
                }
                return delegateAdapter.fromJsonTree(jsonElement);
            }
        }.nullSafe();
    }

}

用於Retrofit的數據解析:

        api = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(new GsonBuilder()
                        .serializeNulls()
                        .registerTypeAdapterFactory(new ResponseTypeAdapterFactory()).create()))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(createOkHttp())
                .baseUrl(baseUrl)
                .build().create(Api.class);

介紹一下上面代碼用到的API

1.

在Gson 2.2中使用了一個新的API,該API getDelegateAdapter()允許您查找Gson默認情況下將使用的適配器。如果您只想調整標準行爲,則委託適配器非常方便。與完全自定義類型的適配器不同,它們在添加和刪除字段時會自動保持最新狀態。

final TypeAdapter<T> delegateAdapter = gson.getDelegateAdapter(this, type);

寫成defaultAdapter更貼切。

2.

獲取指定類型格式typeAdapter

final TypeAdapter<JsonElement> jsonElementAdapter = gson.getAdapter(JsonElement.class);

3.

JsonReader 移步:每天記錄學習的新知識 :JsonReader

4.

TypeAdapter移步:每天記錄學習的新知識 :TypeAdapter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章