2017-06-08 27 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肯定有意義。