3

私は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 文字列: (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」: 真、
        "message_text": "こんにちは",
        "パートナー" : { "country_code" : "za",
            "性別男性"、
            "ニックネーム" : "ニックネーム",
            "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,
        「タイプ」:「シャウトアウト」
      }、
      { "attachment_url" : null,
        "attachment_url_full_size": null,
        "expires_at" : 1363264081,
        「have_attachment」: false,
        "message_text" : "こんにちは",
        "パートナー" : { "country_code" : "za",
            "性別男性"、
            "ニックネーム" : "マーク",
            "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,
        「タイプ」:「シャウトアウト」
      }
    ]
}

スタックトレース:

 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:
4

1 に答える 1

2

インスタンスtが任意のAndroidビュー コンポーネント (たとえば、Button など) から拡張されている場合、または任意のAndroidビュー コンポーネントから拡張されたクラスのフィールドがある場合、そのような例外が発生することがわかりました。

何らかの理由で、このライブラリはビューコンポーネントをシリアル化できなくなりました。したがって、除外戦略を追加できます。たとえば、この戦略は、注釈 @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;
    }

}

ps私の英語でごめんなさい)

于 2013-04-04T18:05:03.990 に答える