2017-06-08 25 views
0

在我的应用程序之一,我有我用它来从我们的服务器加载数据和反序列化他们唱GSON像这样的通用凌空Web服务:安卓:GSON反序列化后计算性能完成

@Override 
protected Response<T> parseNetworkResponse(NetworkResponse response) { 
    try { 
     String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 
     T parsedJson = mGson.fromJson(json, mType); 
     return Response.success(parsedJson, HttpHeaderParser.parseCacheHeaders(response)); 
    } catch (Exception e) { 
     return Response.error(new ParseError(e)); 
    } 
} 

现在的一个我反序列化的对象有点特殊,因为它的json模型包含两个列表,但在代码中我需要一个字典,其中第一个列表对象的id是键,第二个列表对象的数组是值。

我还需要对这两个列表进行反序列化后进行排序。 (我请求我们的后端开发人员进行排序并为我提供一个合适的json模型,但他们拒绝这么做,不要问我为什么......)。

无论如何,现在我需要一种方法来做排序以及属性的计算。

在iOS中,我使用的是SwiftyJson,它不是真正的GSON自动JSON反序列化,但是我可以在后台线程中计算和排序必要字段,以便对对象进行“反序列化”。

虽然在Android上,我有这个泛型函数,因此不知道目前我正在反序列化哪个对象,并且就我而言,GSON使用默认构造函数并直接写入字段而不是使用setter。

所以现在我卡住了。我想知道什么时候最好的情况是计算我的领域。我想过这些方法:

  1. 添加一个瞬态布尔值来检查我是否已经排序了列表。当访问列表的getter时,第一次是错误的,所以我知道我必须排序。我对列表进行排序,将排序后的列表存回,然后将其返回。对于计算字典,我只需要检查它是否为空,如果是这样,计算它
  2. 用一种方法实现某种类型的PostDeserializable接口。在通用Web服务中,我可以检查T parsedJson是否是该接口的实例,如果是,请调用它的方法。

后者将有优势,它会在后台运行,但我也必须记住,该接口(这可能是新手开发谁不知道它的问题)。然而,第一个可能会产生影响,因为它很可能会在UI线程中运行。

我想知道GSON中是否有默认的方式来执行一些后序列化方法,可能是通过注释?希望你能用最少的自定义代码来帮助我找到最好的方法。

+0

它是否符合您的需求:https://github.com/google/gson/tree/master/extras/src/main/java/com/google/gson/interceptors? –

+0

这看起来完全像我想我会需要的。不幸的是,这不是通过gradle可用,所以我想我可以使用我自己的接口,所以我没有所有其他gson额外的开销 – xxtesaxx

+0

是的,你是对的,这只是gson-extras,这不是作为全球发布的产品发布。您可以借用该代码并对其进行修改以适应您的需求。 –

回答

0

好吧,显然没有默认的做法。虽然有一个与我在原始文章中建议的类似的界面,但它仅在不通过maven发布的gson-extras中可用,因此不能简单地将其包含在gradle文件中。相反,人们必须手动下载并保持最新状态。

对我来说,这似乎是不必要的工作,包括整个gson额外的只是这一个接口似乎有点超过顶部。在测试了两种方法之后,我想我会坚持我提出的接口解决方案。

我改变了我的JSON凌空基本要求(从我所有的JSON请求继承)以下:

@Override 
protected Response<T> parseNetworkResponse(NetworkResponse response) { 
    try { 
     String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 
     T parsedJson = mGson.fromJson(json, mType); 

     if (parsedJson instanceof PostDeserializable) { 
      PostDeserializable postDeserializable = (PostDeserializable) parsedJson; 
      postDeserializable.postDeserialization(); 
     } 

     if (parsedJson instanceof Object[]) { 
      Object[] array = (Object[]) parsedJson; 
      for(Object value : array) { 
       if (value instanceof PostDeserializable) { 
        PostDeserializable postDeserializable = (PostDeserializable) value; 
        postDeserializable.postDeserialization(); 
       } 
      } 
     } 

     return Response.success(parsedJson, HttpHeaderParser.parseCacheHeaders(response)); 
    } catch (Exception e) { 
     return Response.error(new ParseError(e)); 
    } 
} 

的PostSerializable界面看起来很简单,以及:

public interface PostDeserializable { 
    void postDeserialization(); 
} 

而对于使用它,我所要做的就是在我的模型POJO上实现它。请注意,我检查T parsedJson本身是否是我的接口的一个实例,以及我检查它是否为数组,如果是,则检查数组中的对象是否属于该类型。

对我来说,这已经足够了,因为如果顶级对象是它的一个实例,或者顶级对象是PostSerializables的数组,我只需要每一个都需要PostSerializable。

这不是一个通用的解决方案,因为它不包括案例,其中PostSerializable例如在另一个模型的第二级。

在这种情况下,我认为使用gson-extras肯定有意义。