问题描述
我有一个自定义对象的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作为私有成员的自定义对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!