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 = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Location.class,new LocationDeserializer()); gsonBuilder.registerTypeAdapter(Location.class,new LocationSerializer()); Gson gson = gsonBuilder.create(); ...
这应该照顾它.