Dan*_*n J 7 android location gson
我继承了一些代码,使用Gson将我们的应用程序状态保存为JSON,然后使用fromJson读取它.
Gson gson = createGson();
gson.fromJson(objString, myClass);
Run Code Online (Sandbox Code Playgroud)
保存的其中一个字段是位置.不幸的是,非常偶尔解析保存的数据失败,因为我保存的Location在其mExtras中包含一个mClassLoader,而Gson库无法使用此错误创建ClassLoader:
RuntimeException:无法调用受保护的java.lang.ClassLoader()而没有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>
}
Run Code Online (Sandbox Code Playgroud)
下面是代码未崩溃时mExtras包含的示例:
"mExtras": {
"mParcelledData": {
"mOwnsNativeParcelObject": true,
"mNativePtr": 1544474480
},
"mHasFds": false,
"mFdsKnown": true,
"mAllowFds": true
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*ach 21
问题是你试图直接将系统提供的类(Location)转换为JSON.而且,正如您所看到的,在序列化内部状态/ Java特定事物时会遇到问题.JSON是一种传递信息的半通用方式.
您不能轻易使用@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, Type type,
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在在您的代码中使用GsonBuilder并注册类:
...
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Location.class, new LocationDeserializer());
gsonBuilder.registerTypeAdapter(Location.class, new LocationSerializer());
Gson gson = gsonBuilder.create();
...
Run Code Online (Sandbox Code Playgroud)
这应该照顾它.