我正在成功使用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);
。
有什么想法吗?
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:
答案 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。抱歉我的英文)