android – Gson中的RuntimeException解析JSON:无法调用受保护的java.lang.ClassLoader()而没有args

前端之家收集整理的这篇文章主要介绍了android – Gson中的RuntimeException解析JSON:无法调用受保护的java.lang.ClassLoader()而没有args前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我继承了一些代码,使用Gson将我们的应用程序状态保存为 JSON,然后使用 fromJson读取它.
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
}

解决方法

问题是你试图直接将系统提供的类(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,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(); 
...

这应该照顾它.

原文链接:https://www.f2er.com/android/317642.html

猜你在找的Android相关文章