這篇要來說的是 AutoValue 如何搭配【Gson】一塊使用,
由於已經將 Model 內原先的field變更為 abstract method 了,
可想而知在 Gson de/serialize 的過程中會發生問題!
ps.如果不了解 Gson 可以先參考我的另一篇文章,
不做任何處理的話會發現在 call Gson 的 fromJson() 時會噴出 Exception,
java.lang.RuntimeException: Failed to invoke public com.yourpackagename.Book() with no args
如果要讓 Gson 成功的序列化,就必須給它一個新的 parse 規則(預設規則不適用在我們的 AutoValue Model 身上),這邊我們一樣會用到一個 library【auto-value-gson】
接下來只需要幾個簡單步驟:
一、在 Model 類別內新增靜態的 typeAdapter() method
二、新增一個抽象類實作 TypeAdapterFactory,並添加一個可產生物件的靜態 method
三、使用 GsonBuilder 來 create Gson,並給予我們自訂義的 TypeAdapterFactory
Gradle:
//auto-value-gson provided 'com.ryanharter.auto.value:auto-value-gson:0.4.6' annotationProcessor 'com.ryanharter.auto.value:auto-value-gson:0.4.6'
After:
//步驟一 @AutoValue public abstract class Book { public abstract String name(); public abstract int price(); public abstract String author(); public static Book create(String name, int price, String author) { return new AutoValue_Book(name, price, author); } public static TypeAdapter<Book> typeAdapter(Gson gson) { return new AutoValue_Book.GsonTypeAdapter(gson); } }
//步驟二 @GsonTypeAdapterFactory public abstract class GsonAdapterFactory implements TypeAdapterFactory { public static TypeAdapterFactory create() { return new AutoValueGson_GsonAdapterFactory(); } }
//步驟三 String jsonString = "{\"author\":\"Anson\",\"name\":\"安森瓦舍\",\"price\":87}"; Gson gson = new GsonBuilder().registerTypeAdapterFactory(GsonAdapterFactory.create()).create(); //serialize Book book = gson.fromJson(jsonString, Book.class); //deserialize System.out.println(gson.toJson(book));
這邊特別要注意的是【步驟二】的 return new AutoValueGson_GsonAdapterFactory() 的部分,
如果你在【步驟一】的 model 中沒有 typeAdapter 的靜態方法,那麼在 build project 時,AutoValueGson_GsonAdapterFactory 是不會被創建出來的。所以步驟可別亂掉!
最後,我在github上創建了一個Project來演示AotoValue與Rxjava2、Retrofit2搭配使用的範例。
延伸閱讀:
● 最簡潔的Model層 - AutoValue 使用介紹【一】
● 最簡潔的Model層 - AutoValue 使用介紹【二】