Gson在>上抛出异常4.0设备

时间:2013-03-14 13:02:02

标签: android gson

我正在成功使用Gson将json放入对象中。它就像Android 2.2(模拟器和真实设备)的设备上的魅力,当我部署到Android 4.0及更高版本(模拟器和设备)时,我得到了这个非常奇怪的异常。

我已经确认json字符串没有问题,因为相同的代码在旧设备上运行得很快。

这个例外肯定会被抛到这里:

Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); return gson.fromJson(jsonString, t);

fromJson方法中的

有什么想法吗?

Json String :(必须从json中的url中删除http://)     

{ "session_id" : "a89d8cd07e356",
    "shoutout_items" : [ { "attachment_url" : "xxxxxx.mobi/pic.php?id=478ba67a44d",
        "attachment_url_full_size" : "xxxxxx.mobi/pic.php?id=01810a5e9f6e7065cd4",
        "expires_at" : 1363264081,
        "have_attachment" : true,
        "message_text" : "Hi",
        "partner" : { "country_code" : "za",
            "gender" : "male",
            "nickname" : "nick",
            "profile_pic_full_size_url" : "xxxxxx.mobi/pic.php?id=810a5e9f6e7065cd43629f1",
            "profile_pic_url" : "xxxxxx.mobi/pic.php?id=23ca67a44d23",
            "profile_summary" : "20,  DBN"
          },
        "shoutout_id" : 31170,
        "type" : "shoutout"
      },
      { "attachment_url" : null,
        "attachment_url_full_size" : null,
        "expires_at" : 1363264081,
        "have_attachment" : false,
        "message_text" : "hello",
        "partner" : { "country_code" : "za",
            "gender" : "male",
            "nickname" : "mark",
            "profile_pic_full_size_url" : "xxxxxx.mobi/pic.php?id=2db9e7f86b9bf7ca",
            "profile_pic_url" : "xxxxxx.mobi/pic.php?id=b110191f1afac",
            "profile_summary" : "40,  DBN"
          },
        "shoutout_id" : 31322,
        "type" : "shoutout"
      }
    ]
}

堆栈跟踪:

 03-14 14:56:02.200: E/AndroidRuntime(19588): FATAL EXCEPTION: main
    03-14 14:56:02.200: E/AndroidRuntime(19588): java.lang.RuntimeException: Unable to start activity ComponentInfo{mobi.smiggle.android/mobi.smiggle.android.MainFragmentActivity}: java.lang.IllegalArgumentException: class android.text.BoringLayout declares multiple JSON fields named m_paint
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1159)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at android.os.Handler.dispatchMessage(Handler.java:99)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at android.os.Looper.loop(Looper.java:137)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at android.app.ActivityThread.main(ActivityThread.java:4507)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at java.lang.reflect.Method.invokeNative(Native Method)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at java.lang.reflect.Method.invoke(Method.java:511)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at dalvik.system.NativeStart.main(Native Method)
    03-14 14:56:02.200: E/AndroidRuntime(19588): Caused by: java.lang.IllegalArgumentException: class android.text.BoringLayout declares multiple JSON fields named m_paint
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:122)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.Gson.getAdapter(Gson.java:353)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.Gson.getAdapter(Gson.java:353)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.Gson.getAdapter(Gson.java:353)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.Gson.getAdapter(Gson.java:353)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.Gson.getAdapter(Gson.java:353)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.Gson.getAdapter(Gson.java:353)
    03-14 14:56:02.200: E/AndroidRuntime(19588):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:

1 个答案:

答案 0 :(得分:2)

我发现,如果您的实例 t 从任何 android 视图组件(例如Button)延伸,或者具有类的字段,则从任何 android 视图组件,你都会得到这样的异常

由于某种原因,此库无法再序列化 view 组件。因此,您可以添加排除策略。例如,此策略将排除所有字段,但带有注释@SerializedName:

的字段除外
class Exclude implements ExclusionStrategy {

@Override
public boolean shouldSkipClass(Class<?> arg0) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean shouldSkipField(FieldAttributes field) {
    SerializedName sn = field.getAnnotation(SerializedName.class);
    if(sn != null)
        return false;
    return true;
}}

假设我们有样本Json:

private final String jsonSample= "{ \"Sample\": { \"field1\":1, \"field2\":2}}";

这是示例代码:

 private void parseJson(){
    Exclude ex = new Exclude();
    Gson gson = new GsonBuilder().create();

    GsonObject gObject = gson.fromJson(jsonSample, GsonObject.class);

}

class GsonObject{
    @SerializedName("Sample")
    public Smpl smpl;

//  private Button btn;  <-- Uncomment this line, and you will get your error!

    class Smpl{
        @SerializedName("field1")
        int fl1;
        @SerializedName("field2")
        int fl2;
    }
}

但是在添加了排除策略后,我已经写过:

    Exclude ex = new Exclude();
    Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();

一切正常。

最后我们有以下测试应用程序:

public class MainActivity extends Activity {

private final String jsonSample= "{ \"Sample\": { \"field1\":1, \"field2\":2}}";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    parseJson();
}

private void parseJson(){
    Exclude ex = new Exclude();
//  Gson gson = new GsonBuilder().create(); <-- without EX strategy it will try to serrialaze Button field in our GsonObject, and throws an exeption
    Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();

    GsonObject gObject = gson.fromJson(jsonSample, GsonObject.class);

    Toast.makeText(this, "Gson" + gObject.smpl.fl1 + " " + gObject.smpl.fl2, Toast.LENGTH_LONG).show();

}

class GsonObject{
    @SerializedName("Sample")
    public Smpl smpl;

    private Button btn; // <-- this field is our reason of this strange exception on Gson serialization

    class Smpl{
        @SerializedName("field1")
        int fl1;
        @SerializedName("field2")
        int fl2;
    }
}
}

class Exclude implements ExclusionStrategy {

    @Override
    public boolean shouldSkipClass(Class<?> arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean shouldSkipField(FieldAttributes field) {
        SerializedName ns = field.getAnnotation(SerializedName.class);
        if(ns != null)
            return false;
        return true;
    }

}

P.S。抱歉我的英文)