Len*_*art 9 serialization android gson sharedpreferences
我想序列化一个自定义Java对象,所以我可以SharedPreferences用来存储它并在另一个Activity中检索它.我不需要持久存储,SharedPreferences我在应用程序关闭时擦除它们.我目前正在使用GSON,但它似乎不适用于Android的SparseArray类型.
我的对象:
public class PartProfile {
private int gameId;
// Some more primitives
private SparseArray<Part> installedParts = new SparseArray<Part>();
// ...
}
public class Part {
private String partName;
// More primitives
}
Run Code Online (Sandbox Code Playgroud)
连载:
Type genericType = new TypeToken<PartProfile>() {}.getType();
String serializedProfile = Helpers.serializeWithJSON(installedParts, genericType);
preferences.edit().putString("Parts", serializedProfile).commit();
Run Code Online (Sandbox Code Playgroud)
serializeWithJSON():
public static String serializeWithJSON(Object o, Type genericType) {
Gson gson = new Gson();
return gson.toJson(o, genericType);
}
Run Code Online (Sandbox Code Playgroud)
反序列化:
Type genericType = new TypeToken<PartProfile>() {}.getType();
PartProfile parts = gson.fromJson(preferences.getString("Parts", "PARTS_ERROR"), genericType);
SparseArray<Part> retreivedParts = parts.getInstalledParts();
int key;
for (int i = 0; i < retreivedParts.size(); i++) {
key = retreivedParts.keyAt(i);
// Exception here:
Part part = retreivedParts.get(key);
// ...
}
Run Code Online (Sandbox Code Playgroud)
例外:
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.mypackage.objects.Part
Run Code Online (Sandbox Code Playgroud)
我不明白为什么Gson想要投射LinkedTreeMap到我的对象,我从来没有在我的整个程序中使用过.HashMap<Integer,Part>在我改用之前我曾经有过一次SparseArray<Part>,从来没有遇到过这个问题.Gson不支持SparseArrays,或者我这边有错误吗?
编辑:似乎SparseArray正确反序列化,但不是内部的对象.而不是LinkedTreeMaps,这些应该是类型Part.
dma*_*ato 13
真的有一种方法可以序列化任何一种SparseArray,这里有一个示例代码:
public class SparseArrayTypeAdapter<T> extends TypeAdapter<SparseArray<T>> {
private final Gson gson = new Gson();
private final Class<T> classOfT;
private final Type typeOfSparseArrayOfT = new TypeToken<SparseArray<T>>() {}.getType();
private final Type typeOfSparseArrayOfObject = new TypeToken<SparseArray<Object>>() {}.getType();
public SparseArrayTypeAdapter(Class<T> classOfT) {
this.classOfT = classOfT;
}
@Override
public void write(JsonWriter jsonWriter, SparseArray<T> tSparseArray) throws IOException {
if (tSparseArray == null) {
jsonWriter.nullValue();
return;
}
gson.toJson(gson.toJsonTree(tSparseArray, typeOfSparseArrayOfT), jsonWriter);
}
@Override
public SparseArray<T> read(JsonReader jsonReader) throws IOException {
if (jsonReader.peek() == JsonToken.NULL) {
jsonReader.nextNull();
return null;
}
SparseArray<Object> temp = gson.fromJson(jsonReader, typeOfSparseArrayOfObject);
SparseArray<T> result = new SparseArray<T>(temp.size());
int key;
JsonElement tElement;
for (int i = 0; i < temp.size(); i++) {
key = temp.keyAt(i);
tElement = gson.toJsonTree(temp.get(key));
result.put(key, gson.fromJson(tElement, classOfT));
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它你需要在你的Gson对象中注册它,如下所示:
Type sparseArrayType = new TypeToken<SparseArray<MyCustomClass>>() {}.getType();
Gson gson = new GsonBuilder()
.registerTypeAdapter(sparseArrayType, new SparseArrayTypeAdapter<MyCustomClass>(MyCustomClass.class))
.create();
Run Code Online (Sandbox Code Playgroud)
你可以在这个要点中找到这个例子.
PS:我知道它根本没有优化,但它只是一个例子来说明如何实现你所需要的.
似乎SparseArray正确反序列化,但不是内部的对象.而不是LinkedTreeMaps,这些应该是Part类型.
你的观察是正确的,因为SparseArray包含Object(不是Part),Gson将没有任何线索将Part作为你的对象类型.因此,它将您的列表映射为其臭名昭着的内部类型LinkedTreeMap.
要解决它,我认为你将无法使用SparseArray...或者你可以尝试retreivedParts.get(key).toString(),然后使用gson再次解析对象.但我认为这样做并不高效
| 归档时间: |
|
| 查看次数: |
6202 次 |
| 最近记录: |