Class Not Found Exception When object implements Parcelable - android

I'm trying to pass custom object between two activities, the custom object has array list of objects and both of them are implementing parcelable interface. When trying to read array list of objects the object from index 1 onwards is null and am getting an error as Class Not Found Exception.
Note: am using createTypedArrayList and writeTypedArrayList respectively to read and write from parcel any help is appreciated.

Try this:
public void writeToParcel(Parcel out, int flags) {
out.writeTypedList(_devices);
}
private SomeClass(Parcel in) {
in.readTypedList(_devices, SomeClass.CREATOR);
}
all code details you may found here.
P.S. You can write/read only primitive type with Parcelable. Do not look at the language, just read the code :)

Related

Correct way of implementing Parcelable

What is the correct way of implementing the Parcelable interface in Android? According to the documentation you should implement the writeToParcel method and have a CREATOR.
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
But when I implement it without adding a CREATOR and leaving the writeToParcel() empty the app still seems to work correctly. Sometimes I would get a Bad Parcelable Exception but I can't work out the steps to replicate.
This is how I use to pass an object from activity to fragment
Bundle bundle = new Bundle();
bundle.putParcelable(PageFragment.PAGE_FILTER_KEY, page);
fragment.setArguments(bundle);
So, what is the purpose of adding stuff like out.writeInt(mData); what kind of problems can be expected if this is not done?
Parcelable implementation mainly have two process steps.
1 Writing your java object to Parcel which includes two methods.
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(cityName);
dest.writeString(macroName);
dest.writeString(id);
}
where describe content is for setting a flag for your contents. Most of time you just need to it untouched.
public void writeToParcel(Parcel dest, int flags) , you need to write you Java class object to parcel step by step according to fields in JAVA class. In above example my class has three strings. You can write almost all types of objects in parcel. You just need to chose appropriate one. Like writeString(),writeList() or writeObject() etc.
2. Second part is reading your java object back from parcel
This part required two things as well. First is CREATOR of your java class like following
public static final Creator<City> CREATOR = new Creator<City>() {
#Override
public City createFromParcel(Parcel in) {
return new City(in);
}
#Override
public City[] newArray(int size) {
return new City[size];
}
};
In above example my Java class is City. It makes read a City object from parcel. But it calls new City(in) constructor of City class. So now I need a constructor which accept a parcel object in arguments. Lets create that too..
protected City(Parcel in) {
cityName = in.readString();
macroName = in.readString();
id = in.readString();
}
Now we make a class complete full proof parcelable. One thing to notice, we need to read members in same sequence at protected City(Parcel in) we put them in parcel i.e. in writeToParcel() method.
On how to reproduce badParcelable exeption in simply letting android create java object from parcelable. For that you can choose Destroy activities from developer options on android device and put you app in background in that activity, so android kill your application process ID. Resume your app by recreating activity (onCreate + Bundle), you will get that exception if you does not implemented parcelable correctly.
But when I implement it without adding a CREATOR and leaving the writeToParcel() empty the app still seems to work correctly.
CREATOR is used when reading data back out of a Parcel and converting it back into objects.
writeToParcel() puts your data into the Parcel.
The only way that leaving those off will work correctly is in cases where your Parcelable is not actually being put into a Parcel or reconstituted from a Parcel. Examples include LocalBroadcastManager.
what is the purpose of adding stuff like out.writeInt(mData);
It would be the same purpose as adding stuff like out.write() with an OutputStream: it writes to the output. Your question is akin to asking "hey, if I don't write data to my file, what sorts of problems will I encounter?".

Android Parcelable: reading and writing

I want to make a custom entity class Parcelable.. I have some fields in it: a String[] and another custom entity object (which is parcelable).. I want to know how to read and write these objects and lists..
public class CustomEntity implements Parcelable {
private int number;
private String[] urls;
private AnotherEntity object;
public CustomEntity(Parcel in) {
number = in.readInt();
// how should I read urls?
// how should I read object?
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(number);
// how should I write urls?
// how should I write object?
}
}
For a String[] you can use the API
parcel.writeStringArray(url)
For AnotherEntity you need to extend it with Parcelable again
parcel.writeParcelable();
https://github.com/mcharmas/android-parcelable-intellij-plugin use this plugin!
Your AnotherEntity must implemented Parcelable too!
I definitely think you should NOT handle the boilerplate yourself.
There are libraries around like Parceler where with only one annotation on your POJO and one line like Parcel.wrap or Parcel.unwrap you can do instant serialization.

Passing object (with multidimensional array) from intent to another

I have a simplest object, and for this I use parcelable. But this object is more complex, have multidimensional array and I really don't know how to write the parcelable methods:
public class PointSystem
{
private int point;
private boolean [] vec1;
private HashSet <Integer> hs1;
private int [][] vecMap;
}
I removed the other istance variable of the same type and the methods so the code is more readable.
I tried with serializable but I don't know how to cast from the other intent the serializable that I get to array [][].
How could I make this object parcelable? Or there're other way to pass this object to another intent?
First off, you say you try to cast the serializable you get to array[][], are you trying to pass all of the members of this object as separate extras? Why not serialize the entire PointSystem object and pass it as an extra. Then, when you try to receive it:
PointSystem p = (PointSystem) getIntent().getSerializableExtra("Extra_Name");
int[][] vecMap = p.vecMap;
A good example of using Parcelable can be found within this answer

How to parcel custom list on Android?

First of all, all the code i will refer to is at my repository
I have been having problems parcelizing a PlayList, the parcelizing works wonders but the deserializing ends up on either a NullPointerException or a BadParcelableException. I haven't been able to pinpoint the source of the exceptions, thus i ask you to check my code to see if i'm abusing any OOP principles or outright misusing the API.
You can't pass the all the class as a parameter to parcel.write(). You need to pass just the parameter copy received in the constructor. You also need to ensure that all objects manipulated are or implement ´Parcelable`.
I believe you need to change the follwing:
In constructor
ArrayList<Song> copy;
public PlayList(ArrayList<Song> copy){
super(copy);
this.copy = copy;
}
In write()
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeTypedList(copy);
parcel.writeInt(actualSong);
parcel.writeInt(shuffling ? 1 : 0);
parcel.writeInt(repeating ? 1 : 0);
}
In read()
public PlayList(Parcel serialized) {
super(serialized.readTypedList(copy, Song.WptType.CREATOR));
actualSong = serialized.readInt();
shuffling = serialized.readInt() == 1 ? true : false;
repeating = serialized.readInt() == 1 ? true : false;
}
NOTE
You also need to implement Parcelable in the Song class for this to work, but it looks already done in the code repository.

Android Parcelable and Serializable

So i know it is recommended to use Parcelable instead of Serializable in android, because it is faster.
My question is: is that impossible to avoid using Serializable right?
If I have a custom object i want to serialize, let's say I have the following class definition
public class Person {
String name;
int Age;
...
....
}
Making this parcelable is easy, because the Person class contains the types parcel.write*() supports, i.e. there is parcel.writeString and parcel.writeInt
Now, what if the Person class is the following:
public class PersonTwo {
MyCustomObj customObj;
String name;
int Age;
...
....
}
How am I suppose to parcel the MyCustomObj object??
It seems I need to use serializable again? but again, I thought it is SLOW to use serializable, and seems we have no choice but to use it in this case.
I don't understand
can someone tell me how I would parcel PersonTwo in this case?
The link given by Ajay is the exact what you are looking for, how you can do it.
Well, what you can do is implement Parcelable to your CustomObject1 and create a Parcelable class for it and then you can use that Parcelable class to Parcel it inside another Parcelable class that will Parcel both the CustomObjects.
public class CustomObject1 implements Parcelable {
// parcelable code CustomObject1
}
public class CustomObject2 implements Parcelable {
private CustomObject1 obj1;
// add CustomObject1 here with getter setter
// parcelable code for CustomObject2
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(obj1, flags);
}
private void readFromParcel(Parcel in) {
obj1 = in.readParcelable(CustomObject1.class.getClassLoader());
}
............
}
You need to make MyCustomObj parcelable.
All the composite objects should also be Parcelable. In case, you want to skip an object then don't use it writeToParcel method.
I came to point where Parcelable is an issue for me.
On Android 4.3, I am getting unmarhalling exception, when passing data between
Activities as Parcelable. It works OK on Android 4.0, 4.2 or 4.4.
It should work when changed to Serializable, even though, it is slower.

Categories

Resources