背景:
我刚开始使用Android,我已经了解了Intents和ListView
。我正在创建一个简单的应用程序,用户输入一些信息,并将该信息添加到ListView中。为此,我在MainActivity类中创建了一个ListView。为名为User
的对象创建了一个类,并创建了自定义ArrayAdapter UserAdapter.
我的User
和UserAdapter
都实现了Serializable
标记接口。现在,只要有人点击MainActivity
类中的按钮添加数据,就会打开一个新的Intent并从该intent获取输入并返回MainActivity
意图。我在意图之间传递UserAdapter
对象。
问题:
现在,适配器对象显示的问题在下一个Intent中不起作用。
代码:
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//blah blah blah ...
// Main code starts here
ListView listView = (ListView) findViewById(R.id.list);
ArrayList<User> arrayList = new ArrayList<>();
UserAdapter adapter = new UserAdapter(this, arrayList);
listView.setAdapter(adapter);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), AddUser.class);
intent.putExtra("adapter", adapter);
startActivity(intent);
}
});
}
//blah blah blah ...
}
UserAdapter.java
public class UserAdapter extends ArrayAdapter<User> implements Serializable {
public UserAdapter(Context context, Collection<User> arrayList) {
//call ArrayAdapter's constructor
//context, layout, collection
super(context, 0, (ArrayList<User>)arrayList);
}
@Override
public View getView(int position, View obj, ViewGroup parent) {
User user = getItem(position);
if(obj == null) {
obj = LayoutInflater.from(getContext()).inflate(R.layout.user_layout, parent, false);
}
TextView name = (TextView) obj.findViewById(R.id.user_name);
TextView adress = (TextView) obj.findViewById(R.id.user_address);
name.setText(user.getUserName());
adress.setText(user.getUserAddress());
return obj;
}
}
用户类也实现了Serializable,我认为你不需要那个类实现,但如果你愿意,我可以在这里添加。
现在我的第二个Activiy课程 AddUser.java
public class AddUser extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_user);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = ((EditText) findViewById(R.id.name)).getText().toString();
String address = ((EditText) findViewById(R.id.address)).getText().toString();
String contact = ((EditText) findViewById(R.id.contact)).getText().toString();
String college = ((EditText) findViewById(R.id.college)).getText().toString();
User user = new User(name, address);
user.setCollege(college);
user.setContact(contact);
Intent intent = new Intent(v.getContext(), MainActivity.class);
UserAdapter adapter = (UserAdapter)getIntent().getSerializableExtra("Adapter");
adapter.add(user);
finish();
startActivity(intent);
}
});
}
}
logcat的
02-20 18:35:37.264 12074-12074/com.example.deepanshu.customadapter3 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.deepanshu.customadapter3, PID: 12074
java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object (name =com.example.deepanshu.customadapter3.UserAdapter)
at android.os.Parcel.readSerializable(Parcel.java:2380)
at android.os.Parcel.readValue(Parcel.java:2203)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2485)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.BaseBundle.getSerializable(BaseBundle.java:988)
at android.os.Bundle.getSerializable(Bundle.java:845)
at android.content.Intent.getSerializableExtra(Intent.java:5256)
at com.example.deepanshu.customadapter3.AddUser$2.onClick(AddUser.java:47)
at android.view.View.performClick(View.java:4789)
at android.view.View$PerformClick.run(View.java:19881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: java.io.InvalidClassException: android.widget.ArrayAdapter; IllegalAccessException
at java.io.ObjectStreamClass.resolveConstructorClass(ObjectStreamClass.java:712)
at java.io.ObjectStreamClass.newInstance(ObjectStreamClass.java:673)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940)
at android.os.Parcel.readSerializable(Parcel.java:2378)
at android.os.Parcel.readValue(Parcel.java:2203)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2485)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.BaseBundle.getSerializable(BaseBundle.java:988)
at android.os.Bundle.getSerializable(Bundle.java:845)
at android.content.Intent.getSerializableExtra(Intent.java:5256)
at com.example.deepanshu.customadapter3.AddUser$2.onClick(AddUser.java:47)
at android.view.View.performClick(View.java:4789)
at android.view.View$PerformClick.run(View.java:19881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
您无法结帐代码here
同时检查我的Github个人资料中的问题。
答案 0 :(得分:2)
您无法在意图中传递自定义ArrayAdapter
或任何其他BaseAdapter/ArrayAdapter
对象。
如您所知,要在意图中传递任何对象,它应该是Parcelable
或Serializable
。
根据Serializable接口https://developer.android.com/reference/java/io/Serializable.html
的文档序列化机制对对象的类名称进行编码 它的非瞬态字段(包括非公共字段)和 所有这些领域的价值。
这里,当您实现自定义Serializable
类的ArrayAdapter
接口时,它实际上不具备序列化功能,因为当您实现Serializable
接口时,所有字段都参与序列化过程。
但android.widget.ArrayAdapter类本身并未实现Serializable
接口。
因此间接从ArrayAdapter
继承的自定义android.widget.ArrayAdapter
也不是Serializable
。
考虑到您的示例,如评论中所述,请使用startActivityForResult()
调用intent以将对象添加到自定义适配器中。
希望你能理解这一点!
阅读有关序列化过程的更多信息!