Reputation: 498
Background:
I am just starting with Android and I have learned about Intents and ListView
. I have am creating a simple app where a user enter some information and that information is added into ListView. For this I have created a ListView in my MainActivity class. Created a class for Objects named User
and created Custom ArrayAdapter UserAdapter.
Both of my classed User
and UserAdapter
implements Serializable
marker interface. Now whenever someone click on button from MainActivity
class to add data a new Intent opens and takes input from that intent and return back to MainActivity
intent. I am passing UserAdapter
Object between intents.
Problem:
Now the problem Adapter Object is showing is not working in next Intent.
Code:
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;
}
}
User class also implements Serializable and I don't think you need that class implementation but if you want I can add that here.
Now My Second Activiy class 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)
You cannot checkout code here
Also check issue in my Github profile too.
Upvotes: 2
Views: 2219
Reputation: 61
You can't pass your custom ArrayAdapter
or any other BaseAdapter/ArrayAdapter
object in intent.
As you know that to pass any object in intent it should be either Parcelable
or Serializable
.
As per documentation of Serializable interface https://developer.android.com/reference/java/io/Serializable.html
The serialization mechanism encodes an object's class name, the names of its non-transient fields (including non-public fields), and the values of all of those fields.
Here, when you implement Serializable
interface to your custom ArrayAdapter
class, it does not actually gets the ability of Serialization, because when you implement Serializable
interface, all fields takes part in the Serialization process.
But android.widget.ArrayAdapter class itself does not implement Serializable
interface.
So indirectly your custom ArrayAdapter
which inherited from android.widget.ArrayAdapter
, is also not Serializable
.
And considering your example, as mentioned in the comments, please call the intent with startActivityForResult()
to get the object to be added to your custom adapter.
Hope so you can understand this!
Read more about Serialization process!
Upvotes: 2