每天记录学习的新知识 :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

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