使用Gson轉化成實體類中的一個方法,傳的參數是 Type 對象。
fromJson(String json, Type typeOfT)
關於獲取Type對象,我知道的有兩種:
Type type = new TypeToken<T>() {}.getType();
和
Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
一開始在一個抽象類中,通過反射的方法獲取Type對象,實體類用泛型代替,然後將該抽象類作爲參數,傳入具體的實體類。
注意,這裏不能用第一種獲取Type對象的方法,否則會報類型強轉異常。
com.google.gson.internal.LinkedTreeMap cannot be cast to Basebean
使用第二種獲取Type對象方法,具體代碼:
public abstract class RequestCallback<T> extends Callback<T> {
public RequestCallback(){
}
public T parseNetworkResponse(Response response, int i) throws Exception {
String string = response.body().string();
Type type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return new Gson().fromJson(string, type);
}
}
Api.imQueryGroups(imsCookie, userId, new RequestCallback<BaseBean<List<GroupItemBean>>>() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(BaseBean<List<GroupItemBean>> baseBean, int i) {
}
});
這樣就能在使用網絡請求時,返回我們想要的實體類結果了。
PS:
如果對parseNetworkResponse()方法返回的實體具體化,就不會出現問題。就不需要創建一個子類去繼承Callback了。
Api.imQueryGroups(imsCookie, userId, new Callback<BaseBean<List<GroupItemBean>>>() {
@Override
public BaseBean<List<GroupItemBean>> parseNetworkResponse(Response response, int i) throws Exception {
Type type = new TypeToken<BaseBean<List<GroupItemBean>>>() {}.getType();
return new Gson().fromJson(response.body().string(), type);
}
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(BaseBean<List<GroupItemBean>> baseBean, int i) {
}
});
但是這樣的話,每次獲取服務器返回的數據,都得寫一遍Gson的實體類轉化。做重複的事情是多麼的無意義啊,於是我決定另尋辦法。
網上找了好久都沒解決方法,但是搜到了“泛型擦除”,結合自身問題,我覺得很可能就出現在這裏。
泛型擦除:編譯時,泛型類型會改爲Object。
那麼,第一種方法獲取到的泛型是Object,Gson無法轉化成相對應的實體類報錯。
最後改用了第二種獲取Type對象的方法,這種方法沒有使用到泛型,最終編譯成功,數據解析也正常。
參考:
http://blog.csdn.net/gengv/article/details/5178055
https://www.cnblogs.com/baiqiantao/p/7475477.html