Gson gson = createGson(); gson.fromJson(objString,myClass);
其中一个保存的字段是Location.不幸的是,很有可能解析保存的数据失败,因为我保存的Location在其mExtras中包含一个mClassLoader,而Gson库无法使用此错误创建ClassLoader:
RuntimeException: Failed to invoke protected java.lang.classLoader() with no args
有谁知道为什么ClassLoader被包含在我的Location的附加内容中,以及它是否应该以JSON表示结尾?
我假设我可以通过单独保存位置对象中的关键字段(例如经度,纬度,高度,时间,精度)来解决这个问题,但如果可能的话,保存位置对象会很好.
我看到有一个ExclusionStrategy对象可用于排除字段,但我不确定是否可以/应该使用它来排除我位置内的额外内容…
仅供参考,这是我的Location对象的JSON数据(经度和纬度改为隐藏我):
{
<snip>
"lastKNownLocation": {
"mResults": [
0,0
],"mProvider": "gps","mExtras": {
"mParcelledData": {
"mOwnObject": 1,"mObject": 5525040
},"mClassLoader": {
"packages": {}
},"mMap": {},"mHasFds": false,"mFdsKNown": true,"mAllowFds": true
},"mdistance": 0,"mTime": 1354658984849,"mAltitude": 5.199999809265137,"mLongitude": -122.4376,"mLon2": 0,"mLon1": 0,"mLatitude": 37.7577,"mLat1": 0,"mLat2": 0,"mInitialbearing": 0,"mHasspeed": true,"mHasbearing": false,"mHasAltitude": true,"mHasAccuracy": true,"mAccuracy": 16,"mSpeed": 0,"mbearing": 0
},<snip>
}
下面是代码未崩溃时mExtras包含的示例:
"mExtras": {
"mParcelledData": {
"mOwnsNativeParcelObject": true,"mNativePtr": 1544474480
},"mAllowFds": true
}
解决方法
你不能轻易使用@Expose注释,因为它不是你的类;这将需要修改Location的源代码或通过使用jassist在运行时添加它们的相当广泛的过程(参见:http://ayoubelabbassi.blogspot.com/2011/01/how-to-add-annotations-at-runtime-to.html)
查看Location类,我只需创建一个自定义Gson Serializer和Deserializer并完成它.你真正感兴趣的是GPS数据,而不是类本身的内部.您只需使用getter构建包含序列化程序中所需信息的JSON,然后在Deserializer中创建一个新的Location实例,并使用公共setter从提供的JSON中填充信息.
class LocationSerializer implements JsonSerializer<Location>
{
public JsonElement serialize(Location t,Type type,JsonSerializationContext jsc)
{
JsonObject jo = new JsonObject();
jo.addProperty("mProvider",t.getProvider());
jo.addProperty("mAccuracy",t.getAccuracy());
// etc for all the publicly available getters
// for the information you're interested in
// ...
return jo;
}
}
class LocationDeserializer implements JsonDeserializer<Location>
{
public Location deserialize(JsonElement je,JsonDeserializationContext jdc)
throws JsonParseException
{
JsonObject jo = je.getAsJsonObject();
Location l = new Location(jo.getAsJsonPrimitive("mProvider").getAsstring());
l.setAccuracy(jo.getAsJsonPrimitive("mAccuracy").getAsFloat());
// etc,getting and setting all the data
return l;
}
}
现在在您的代码中使用GsonBuilder并注册类:
... GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Location.class,new LocationDeserializer()); gsonBuilder.registerTypeAdapter(Location.class,new LocationSerializer()); Gson gson = gsonBuilder.create(); ...
这应该照顾它.