【问题标题】:Android Kotlin Gson Slow Json DeserializationAndroid Kotlin Gson 慢 Json 反序列化
【发布时间】:2016-08-02 18:48:43
【问题描述】:

我有一个大的 json,我必须反序列化,我只对 if 的某些部分感兴趣。我正在使用的 Pojos 是这样的:

data class Response<T>(
        val header: JHeader,
        val result: T
)

data class JHeader(
        val success: Int,
        val error: List<String>
)

class Character{
    @SerializedName("id_") val id: Int
    @SerializedName("levelA") val level: String
    @SerializedName("a3") val unit: String = ""

    constructor(id: Int, level: String) {
        this.id = id
        this.level= level
    }
}

改装适配器的相关部分:

val retrofit = Retrofit.Builder()
                .addCallAdapterFactory(rxAdapter)
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(BASE_URL)
                .client(httpClient.build())
                .build()

还有Impl:

fun getCharacterById(characterID: Int):Observable<Response<List<Character>>> {
        return apiService.getCharacter(characterID)
                .subscribeOn(Schedulers.io())
    } 

我收到了 300 毫秒的改装调试报告,只需调用此服务即可。

我的问题是:

  • 我什么时候应该考虑使用 TypeAdapter(我选择性能优于样板,我不介意使用类型适配器编写几行额外的代码)。但是我不太明白适配器的用途是什么,我应该在什么情况下使用它们。

  • 我的 Json 结构比我的 Character Pojo 具有更多的属性,我只是意识到使用瞬态 / @Expose 或将其置于 Pojo 之外会导致相同的结果。这三个有区别吗?

  • 当我使用 Kotlin 时,是否有任何库/扩展可以帮助我处理这种 TypeAdapter 反序列化的东西?

【问题讨论】:

  • 我现在也面临着类似的问题。你的 http 响应是多少字节?
  • 200 OK (303ms), END HTTP (49063-byte body)

标签: android kotlin retrofit2


【解决方案1】:

对我来说,实现自定义 TypeAdapter 是一个巨大的性能提升。我为每个需要大量反序列化的类使用类型适配器。在您的示例中,这将是(在 Java 中):

public class CharacterTypeAdapter extends TypeAdapter<Character> {
    @Override
    public void write(final JsonWriter out, final Character character) throws IOException {
        out.beginObject();
        out.name("id").value(character.getId());
        out.name("level").value(character.getLevel());
        out.name("unit").value(character.getUnit());
        out.endObject();
    }

    @Override
    public Character read(final JsonReader in) throws IOException {
        Character character = new Character();
        in.beginObject();
        while(in.hasNext()){
            switch(in.nextName()){
                case "id":
                   character.setId(in.nextInt());
                   break; 
                case "level":
                   character.setId(in.nextString());
                   break;
                case "unit":
                   character.setId(in.nextString());
                   break;
            }
        }
        in.endObject();

        return character;
    }
}

TypeAdapter 必须在您的 Gson 配置中注册,如下所示:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Character.class, new CharacterTypeAdapter());
Gson gson = gsonBuilder.create();

gson 实例必须在 Retrofit 中注册:

 new Retrofit
     .Builder()
     .addConverterFactory(GsonConverterFactory.create(gson))
     .build()
     .createApi(Api.class);

您将获得极快的反序列化。

【讨论】:

  • 是的,我已经意识到它可能是这样的,但我认为我得到了相同的结果,我不知道是不是服务器很慢,我没有办法对默认的 json 反序列化。知道如何测量它吗?
  • 出于某种原因,儿子没有使用我的类型适配器。很奇怪。
  • 似乎无法识别带有自定义 TypeAdapter 对象的通用列表,因此使用了默认的反序列化器。有什么解决方法吗?
  • 我无法确认。我也将它用于通用列表。我看到的唯一区别是我的改造 api 方法不会将结果包装在Response 对象中,即Observable&lt;List&lt;Character&gt;&gt; 而不是Observable&lt;Response&lt;List&lt;Character&gt;&gt;&gt;。我不知道这是否对反序列化有影响。
  • 我几乎可以肯定它确实:p 但可以找到解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多