我如何使用Gson序列化具有Context作为私有成员的自定义对象? [英] How can I serialize a custom object that has a Context as a private member using Gson?

查看:336
本文介绍了我如何使用Gson序列化具有Context作为私有成员的自定义对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义对象的ArrayList,我试图使用Gson作为JSON字符串存储到磁盘。这对我的对象来说很好,它只包含像String这样的基本数据类型,但是我有一个类有一个存储Activity的Context的私有成员。当我尝试使用Gson序列化此类时,出现以下异常:

  java.lang.RuntimeException:无法启动活动ComponentInfo {com.xxxx.xxxx / com.xxxx.xxxx.MainActivity}:java.lang.SecurityException:无法在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)$中创建方法构造函数
b $ b at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1344)
在android.os.Handler.dispatchMessage(Handler.j ava:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang .reflect.Method.invoke(Native方法)
at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit。 main(ZygoteInit.java:616)
导致:java.lang.SecurityException:无法使方法构造函数在java.lang.reflect.Constructor.setAccessible(Constructor.java:336)处可访问

在com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:101)
在com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:83)
在com.google .gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:96)
在com.google.gson.Gson.getAdapter(Gson.java:407)
在com.google.gson.internal .bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access $ 100(ReflectiveTyp eAdapterFactory.java:49)
,位于com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ 1.< init>(ReflectiveTypeAdapterFactory.java:106)
,位于com.google.gson.internal.bind。 ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:105)
,位于com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:161)
,位于com.google.gson.internal.bind。 ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
在com.google.gson.Gson.getAdapter(Gson.java:407)
在com.googl e.gson.internal.bind.ArrayTypeAdapter $ 1.create(ArrayTypeAdapter.java:48)
at com.google.gson.Gson.getAdapter(Gson.java:407)
com.google.gson .internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access $ 100(ReflectiveTypeAdapterFactory.java:49)
com.google。 gson.internal.bind.ReflectiveTypeAdapterFactory $ 1.< init>(ReflectiveTypeAdapterFactory.java:106)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:105)
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:161)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
在com.google.gson.Gson.getAdapter(Gson.java:407)
在com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
在com.google .gson.internal.bind.ReflectiveTypeAdapterFactory.access $ 100(ReflectiveTypeAdapterFactory.java:49)
,位于com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ 1.< init>(R eflectiveTypeAdapterFactory.java:106)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:105)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields( ReflectiveTypeAdapterFactory.java:161)
,位于com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97)
,位于com.google.gson.Gson.getAdapter(Gson.java: 407)
,位于com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:136)
在com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access $ 100(ReflectiveTypeAdapterFactory.java:49)
在com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ 1.< init>(Refle

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


$ b

  public class MainActivity extends AppCompatActivity {
$ b @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(上下文上下文){
this.context = context;




解决方案

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

  public class MyObject {

private transient Context context;

// ...这里的其他字段

public MyObject(){
}

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

}


I have an ArrayList of custom objects that I'm trying to store to disk as a JSON String using Gson. This works great for my objects that just contain basic types of data like Strings, but one class I have has a private member that stores the Activity's Context. When I try to serialize this class using Gson, I get the following Exception:

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

I'm guessing the issue is that there is a method inside Context that Gson can't access because it's protected or something similar. So is there a way I can serialize objects that contain other complex objects using Gson?

Here is a short code snippet that will produce the crash:

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;
        }
    }
}

解决方案

Context is not serializable. You should declare variable as transient for preventing it to be serialized. Of course you should assign it manually when deserializing.

public class MyObject {

    private transient Context context;

    // ... other fields here

    public MyObject() {
    }

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

}

这篇关于我如何使用Gson序列化具有Context作为私有成员的自定义对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆