如何使用Gson序列化具有Context作为私有成员的自定义对象?

时间:2016-01-21 23:34:50

标签: java android serialization gson

我有一个自定义对象的ArrayList,我试图使用Gson将其作为JSON字符串存储到磁盘。这适用于我的对象,它只包含基本类型的数据,如字符串,但我有一个类有一个存储Activity的Context的私有成员。当我尝试使用Gson序列化这个类时,我得到以下异常:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxx.xxxx/com.xxxx.xxxx.MainActivity}: java.lang.SecurityException: Can't make method constructor accessible
                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                       at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                       at android.os.Looper.loop(Looper.java:148)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                    Caused by: java.lang.SecurityException: Can't make method constructor accessible
                                                                       at java.lang.reflect.Constructor.setAccessible(Constructor.java:336)
                                                                       at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:101)
                                                                       at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:83)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:96)
                                                                       at com.google.gson.Gson.getAdapter(Gson.java:407)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:49)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:106)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:105)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:161)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
                                                                       at com.google.gson.Gson.getAdapter(Gson.java:407)
                                                                       at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48)
                                                                       at com.google.gson.Gson.getAdapter(Gson.java:407)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:49)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:106)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:105)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:161)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
                                                                       at com.google.gson.Gson.getAdapter(Gson.java:407)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:49)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:106)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:105)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:161)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
                                                                       at com.google.gson.Gson.getAdapter(Gson.java:407)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
                                                                       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:49)
                                                                    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(Refle

我猜测问题是在Context中有一个方法,Gson无法访问,因为它受到保护或类似的东西。那么有没有办法可以使用Gson序列化包含其他复杂对象的对象?

这是一个会产生崩溃的简短代码段:

public class MainActivity extends AppCompatActivity {

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

        MyObject myObject = new MyObject(this);

        Gson gson = new Gson();
        String myObjectJson = gson.toJson(myObject);
    }

    public class MyObject {

        private Context context;

        public MyObject(Context context) {
            this.context = context;
        }
    }
}

1 个答案:

答案 0 :(得分:6)

Context不可序列化。您应该将变量声明为transient,以防止它被序列化。当然,您应该在反序列化时手动分配它。

public class MyObject {

    private transient Context context;

    // ... other fields here

    public MyObject() {
    }

    public void setContext(Context context) {
        this.context = context;
    }

}