Android: OutOfMemoryError when unmarshalling a Parcelable - android

i got a serious problem while trying to unmarshall an ArrayList of custom objects, with an ArrayList of custom objects as a field in it. When i remove everything that has to do with the ArrayList<User> in the Coon.java everything works fine. The error occurs, after including the "readTypedList"-part....Trying to fix that problem the whole day and can't find any solution.
Thanx in advance,
Roberto
Stacktrace: http://pastebin.com/LAGYmW95
Code:
-> Coon.java <-
package development.coonDub.misc;
import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;
public class Coon implements Parcelable {
/**
*
*/
public Coon(Parcel in) {
readFromParcel(in);
}
String name;
String city;
String country;
ArrayList<User> pts = new ArrayList<User>();
public Coon(String name, String city, String country,ArrayList<User> pts) {
this.name = name;
this.city = city;
this.country = country;
this.pts = pts;
}
public String getName() {
return name;
}
public String getCity() {
return city;
}
public String getCountry() {
return country;
}
public ArrayList<User> getPts() {
return pts;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(city);
dest.writeString(country);
dest.writeTypedList(pts);
}
private void readFromParcel(Parcel in) {
name = in.readString();
city = in.readString();
country = in.readString();
in.readTypedList(pts, User.CREATOR);
}
public static final Parcelable.Creator<Coon> CREATOR =
new Parcelable.Creator<Coon>() {
public Coon createFromParcel(Parcel in) {
return new Coon(in);
}
public Coon[] newArray(int size) {
return new Coon[size];
}
};
}
-> User.java <-
package development.coonDub.misc;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
String name;
public static final Parcelable.Creator<User>
CREATOR = new Parcelable.Creator<User>() {
public User createFromParcel(Parcel in) {
return new User(in);
}
public User[] newArray(int size) {
return new User[size];
}
};
public User(String name) {
this.name = name;
}
public User(Parcel in) {
readFromParcel(in);
}
private void readFromParcel(Parcel in) {
name = in.readString();
}
public String getName() {
return name;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
}
-> Activity1.class <-
...
Intent notificationIntent =
new Intent(getApplicationContext(), Activity2.class);
// coons is an ArrayList<Coon>..
notificationIntent.putExtra("coons", coons);
...
-> Activity2.class <-
...
ArrayList<Coon> coons = getIntent().getExtras().getParcelableArrayList("coons");
...

Related

Android getParcelableExtra returns null

I am currently trying to pass some data from my fragment to an activity. I am passing some parameter, and also an arraylist of a model class. I already make sure that the arraylist before I passed it is not null, since I am able to print out the value in log. But it become null in the called activity.
Here is the model class:
public class Product implements Parcelable {
String code, id, status, is_expired;
public Product() {}
public Product(String code, String id, String status, String is_expired) {
this.code = code;
this.id = id;
this.status = status;
this.is_expired = is_expired;
}
public Product(Parcel in) {
code = in.readString();
id = in.readString();
status = in.readString();
is_expired = in.readString();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getIs_expired() {
return is_expired;
}
public void setIs_expired(String is_expired) {
this.is_expired = is_expired;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(code);
dest.writeString(id);
dest.writeString(status);
dest.writeString(is_expired);
}
public static final Parcelable.Creator<Product> CREATOR = new Parcelable.Creator<Product>() {
public Product createFromParcel(Parcel in) {
return new Product(in);
}
public Product[] newArray(int size) {
return new Product[size];
}
};
}
Here is the caller:
intent.putExtra("product", productList);
Here is how retrieve the data:
ArrayList<Product> productList = getIntent().getParcelableExtra("product");
What am I doing wrong here?
Try this .
intent.putParcelableArrayListExtra("product", productList);
And next Activity .
ArrayList<Product> productList = getIntent().getParcelableArrayListExtra("product");

ParcelableException: ClassNotFoundException when unmarshalling

I am sending data from one activity to another activity from different packages.I applied intent to send and receive data.
For sending single value its working but now I want to send object via intent so I implemented Parcelable but I am getting error that class not found.
Here is my code.....
Sender side Classes :-
Sender MainActivity
public class MainActivity extends AppCompatActivity {
Button click;
Student student = new Student(01,"Anjali");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
click = (Button)findViewById(R.id.app1);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent act = new Intent("com.gov.printer");
act.putExtra("data",student);
startActivity(act);
}
});
}
}
Student Sender class
public class Student implements Parcelable {
int id;
String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static Creator<Student> getCREATOR() {
return CREATOR;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
}
public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>()
{
#Override
public Student createFromParcel(Parcel source) {
return new Student(source);
}
#Override
public Student[] newArray(int size) {
return new Student[size]; }
};
private Student(Parcel in){
}
}
Receiver side Classes:-
Student receiver class
public class Student implements Parcelable{
int id;
String name;
public int get Id() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static Creator<Student> getCREATOR() {
return CREATOR;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>()
{
#Override
public Student createFromParcel(Parcel source) {
return new Student(source);
}
#Override
public Student[] newArray(int size) {
return new Student[size];
}
};
private Student(Parcel in){
this.name = in.readString();
this.id = in.readInt();
}
}
Receiver MainActivity
public class MainActivity extends AppCompatActivity {
TextView getdata;
String TAG ="Main";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getdata = (TextView)findViewById(R.id.textapp);
Intent in = getIntent();
if (in.getAction().equals("com.gov.printer"));
{
Student student = in.getParcelableExtra("data");
Log.e(TAG,"data is"+student);
getdata.setText("name:-" +student.getName()+"\n"
+"ID:- " +student.getId());
}
}
You can achieve like this
Student class:
package com.ex.utils;
import android.os.Parcel;
import android.os.Parcelable;
public class Student implements Parcelable {
int id;
String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.name);
}
public Student() {
}
protected Student(Parcel in) {
this.id = in.readInt();
this.name = in.readString();
}
public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() {
#Override
public Student createFromParcel(Parcel source) {
return new Student(source);
}
#Override
public Student[] newArray(int size) {
return new Student[size];
}
};
}
Sender:
Intent i = new Intent("");
i.putExtra("data", student);
Receiver:
Student student = getIntent().getParcelableExtra("data");

Pass ArrayList of Parcelable objects throws error

I have an object with a couple of Strings, one int and another object which has 4 inner objects. All of them implementing Parcelable. In order to generate the boilerplate code, I used Parcelable plugin from Android studio.
Even though all the objects are parcelable, I'm getting the following error: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: AlbumTrackResponse
Here's how the POJOs look like:
Main object:
public class AlbumTrackResponse implements Parcelable {
private String id;
private String albumId;
private String position;
private String title;
private int rate;
private AllServices services;
public AllServices getServices() {
return services;
}
public void setServices(AllServices services) {
this.services = services;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAlbumId() {
return albumId;
}
public void setAlbumId(String albumId) {
this.albumId = albumId;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getRate() {
return rate;
}
public void setRate(int rate) {
this.rate = rate;
}
protected AlbumTrackResponse(Parcel in) {
id = in.readString();
albumId = in.readString();
position = in.readString();
title = in.readString();
rate = in.readInt();
services = (AllServices) in.readValue(AllServices.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(albumId);
dest.writeString(position);
dest.writeString(title);
dest.writeInt(rate);
dest.writeValue(services);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<AlbumTrackResponse> CREATOR = new Parcelable.Creator<AlbumTrackResponse>() {
#Override
public AlbumTrackResponse createFromParcel(Parcel in) {
return new AlbumTrackResponse(in);
}
#Override
public AlbumTrackResponse[] newArray(int size) {
return new AlbumTrackResponse[size];
}
};
}
Inner object with 4 objects
public class AllServices implements Parcelable {
private GigRevService gigrev;
private AppleService apple;
private GoogleService google;
private SpotifyService spotify;
protected AllServices(Parcel in) {
gigrev = (GigRevService) in.readValue(GigRevService.class.getClassLoader());
apple = (AppleService) in.readValue(AppleService.class.getClassLoader());
google = (GoogleService) in.readValue(GoogleService.class.getClassLoader());
spotify = (SpotifyService) in.readValue(SpotifyService.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
public GigRevService getGigrev() {
return gigrev;
}
public void setGigrev(GigRevService gigrev) {
this.gigrev = gigrev;
}
public AppleService getApple() {
return apple;
}
public void setApple(AppleService apple) {
this.apple = apple;
}
public GoogleService getGoogle() {
return google;
}
public void setGoogle(GoogleService google) {
this.google = google;
}
public SpotifyService getSpotify() {
return spotify;
}
public void setSpotify(SpotifyService spotify) {
this.spotify = spotify;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(gigrev);
dest.writeValue(apple);
dest.writeValue(google);
dest.writeValue(spotify);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<AllServices> CREATOR = new Parcelable.Creator<AllServices>() {
#Override
public AllServices createFromParcel(Parcel in) {
return new AllServices(in);
}
#Override
public AllServices[] newArray(int size) {
return new AllServices[size];
}
};
}
The inner objects from here contain just string items.
Here's how I pass the ArrayList to the bundle:
bundle.putParcelableArrayList(MediaPlayerService.TRACK_LIST, trackList);
I'm passing the items from an Activity to a Service. Any ideas why I'm getting this error?
EDIT: Implementation of service classes
public class GoogleService implements Parcelable {
private String name;
private String uri;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
protected GoogleService(Parcel in) {
name = in.readString();
uri = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(uri);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<GoogleService> CREATOR = new Parcelable.Creator<GoogleService>() {
#Override
public GoogleService createFromParcel(Parcel in) {
return new GoogleService(in);
}
#Override
public GoogleService[] newArray(int size) {
return new GoogleService[size];
}
};
}
This looks extremly strange
this.services = in.readParcelable(getClass().getClassLoader());
You are pointing out to the wrong class loader. You have to use it like this
this.services = (AllServices)in.readParcelable(AllServices.class.getClassLoader());
Besides that, I am always using this site http://www.parcelabler.com/ to quickly generate my Parceables. Or you could use it like this
services = (AllServices) in.readValue(AllServices.class.getClassLoader());
Here:
protected AllServices(Parcel in) { this.gigrev = in.readParcelable(getClass().getClassLoader());
this.apple = in.readParcelable(getClass().getClassLoader());
this.google = in.readParcelable(getClass().getClassLoader());
this.spotify = in.readParcelable(getClass().getClassLoader()); }
Replace it with
protected AllServices(Parcel in) { this.gigrev = in.readParcelable(GigRevService.class.getClassLoader());
this.apple = in.readParcelable(AppleService.class.getClassLoader());
this.google = in.readParcelable(GoogleService.class.getClassLoader());
this.spotify = in.readParcelable(SpotifyService.class.getClassLoader()); }
And replace:
this.services = in.readParcelable(getClass().getClassLoader());
With:
this.services = in.readParcelable(AllServices.class.getClassLoader());
Also can you show the GoogleService etc classes? Each inner object's class must have a Parcelable creator also and implement the Parcelable interface as well.

Android use Intent to send a list of Parcelable objects which contain a list of another Parcelable objects

In my Android app, I want to use Intent to pass a list of SingleGroup to another Activity where each SingleGroup object contains a list of SingleImage, here are class for SingleImage and SingleGroup:
public class SingleImage implements Parcelable{
public String name;
public int drawableId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDrawableId() {
return drawableId;
}
public void setDrawableId(int drawableId) {
this.drawableId = drawableId;
}
public SingleImage(String name, int drawableId)
{
this.name = name;
this.drawableId = drawableId;
}
public static final Parcelable.Creator<SingleImage> CREATOR
= new Parcelable.Creator<SingleImage>()
{
public SingleImage createFromParcel(Parcel in)
{
return new SingleImage(in);
}
public SingleImage[] newArray(int size)
{
return new SingleImage[size];
}
};
private SingleImage(Parcel in)
{
name = in.readString();
drawableId = in.readInt();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(drawableId);
}
}
Here is SingleGroup class:
public class SingleGroup implements Parcelable{
private static final String TAG = "SINGLEGROUP";
private ArrayList<SingleImage> images = new ArrayList<SingleImage>(0);
private String myTitle;
private String groupDesc;
public SingleGroup(String mTitle, String desc, ArrayList<SingleImage> imagesList) {
this.myTitle = mTitle;
this.groupDesc = desc;
this.images = imagesList;
}
public String getGroupDesc() {
return groupDesc;
}
public String getMyTitle() {
return myTitle;
}
public void setMyTitle(String myTitle) {
this.myTitle = myTitle;
}
public ArrayList<SingleImage> getImages() {
return images;
}
public void setImages(ArrayList<SingleImage> images) {
this.images = images;
}
public static final Parcelable.Creator<SingleGroup> CREATOR
= new Parcelable.Creator<SingleGroup>()
{
public SingleGroup createFromParcel(Parcel in)
{
return new SingleGroup(in);
}
public SingleGroup[] newArray(int size)
{
return new SingleGroup[size];
}
};
private SingleGroup(Parcel in)
{
myTitle = in.readString();
groupDesc = in.readString();
//problem maybe here
in.readTypedList(images,SingleImage.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(myTitle);
dest.writeString(groupDesc);
//problem maybe here
dest.writeTypedList(images);
}
#Override
public String toString() {
String result = "myTitle "+myTitle+" desc "+ groupDesc + " imagesize "+images.size();
return result;
}
}
It works ok when calling to pass ArrayList<SingleImage> through Intent,
while when I called to pass ArrayLlist<SingleGroup> through Intent I got error:
Parcel android.os.Parcel#3c4c6743: Unmarshalling unknown type code
3211379 at offset 224
Any idea? Thanks in advance
---------------- Update ----------------
I have changed in.readTypedList(images, null); to in.readTypedList(images, SingleImage.CREATOR); but it still not working. same unmarshalling error
---------------- Problem Solved --------------
Thanks to Keita. The real problem is not actually listed in my code. When I passing the parcelable object, I should also include some other attributes which I missed.
Strongly recommend AS plugin Android Parcelable code generator
You must be pass SingleImage.CREATOR into method readTypedList instead of "null" value
private SingleGroup(Parcel in)
{
myTitle = in.readString();
groupDesc = in.readString();
//problem maybe here
in.readTypedList(images, SingleImage.CREATOR);
}
Try this one. That is what i always do and it work:
private SingleGroup(Parcel in)
{
myTitle = in.readString();
groupDesc = in.readString();
//problem maybe here
in.createTypedArrayList(SingleImage.CREATOR);
}
ArrayList is serialize. So try to this
public class SingleImage implements Serializable{
....
}
Refer this: ArrayList Android Documentation

Android parcelable readtypedlist out of memory error

I have been trying to debug this out of memory error that's occurring in my parcelable object.
I'm really stuck on this one. I checked the order and it seems correct to me.
import java.util.ArrayList;
import java.util.List;
import android.os.Parcel;
import android.os.Parcelable;
import com.intuch.interfaces.ListRow;
public class ProfileModel implements Parcelable{
public String linkedinID;
public String firstName;
public String lastName;
public String email;
public String pictureURL;
public String headline;
public String industry;
public String interests;
public List<EducationModel> education = new ArrayList<EducationModel>();
public List<PositionModel> position = new ArrayList<PositionModel>();
public boolean introduceOthers;
public boolean answerQuestions;
public boolean beMentor;
public boolean graduated;
public ProfileModel () {
education = new ArrayList<EducationModel>();
position = new ArrayList<PositionModel>();
}
public ProfileModel (Parcel in) {
this();
readFromParcel(in);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(linkedinID);
dest.writeString(firstName);
dest.writeString(lastName);
dest.writeString(email);
dest.writeString(pictureURL);
dest.writeString(headline);
dest.writeString(industry);
dest.writeString(interests);
dest.writeList(education);
dest.writeList(position);
boolean[] myBooleanArr = new boolean[4];
myBooleanArr[0]=introduceOthers;
myBooleanArr[1]=answerQuestions;
myBooleanArr[2]=beMentor;
myBooleanArr[3]=graduated;
dest.writeBooleanArray(myBooleanArr);
}
public static final Parcelable.Creator<ProfileModel> CREATOR = new Parcelable.Creator<ProfileModel>() {
public ProfileModel createFromParcel(Parcel source) {
return new ProfileModel(source);
}
public ProfileModel[] newArray(int size) {
return new ProfileModel[size];
}
};
/*
* Constructor calls read to create object
*/
private void readFromParcel(Parcel in) {
this.linkedinID = in.readString();
this.firstName = in.readString();
this.lastName = in.readString();
this.email = in.readString();
this.pictureURL = in.readString();
this.headline = in.readString();
this.industry = in.readString();
this.interests = in.readString();
in.readTypedList(education, EducationModel.CREATOR);
in.readTypedList(position, PositionModel.CREATOR);
boolean[] myBooleanArr = new boolean[4];
in.readBooleanArray(myBooleanArr);
introduceOthers=myBooleanArr[0];
answerQuestions=myBooleanArr[1];
beMentor=myBooleanArr[2];
graduated=myBooleanArr[3];
}
}
The error occurs in the following line:
in.readTypedList(position, PositionModel.CREATOR);
Here are my other classes:
EducationalModel:
import android.os.Parcel;
import android.os.Parcelable;
public class EducationModel implements Parcelable{
public String degree;
public String schoolName;
public int graduated;
private EducationModel(Parcel in) {
degree = in.readString();
schoolName = in.readString();
graduated = in.readInt();
}
public EducationModel() {
// TODO Auto-generated constructor stub
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(degree);
dest.writeString(schoolName);
dest.writeInt(graduated);
}
public static final Parcelable.Creator<EducationModel> CREATOR = new Parcelable.Creator<EducationModel>() {
public EducationModel createFromParcel(Parcel in) {
return new EducationModel(in);
}
public EducationModel[] newArray(int size) {
return new EducationModel[size];
}
};
}
PositionModel:
import android.os.Parcel;
import android.os.Parcelable;
public class PositionModel implements Parcelable{
public String company;
public String title;
private PositionModel(Parcel in) {
company = in.readString();
title = in.readString();
}
public PositionModel() {
// TODO Auto-generated constructor stub
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(company);
dest.writeString(title);
}
public static final Parcelable.Creator<PositionModel> CREATOR = new Parcelable.Creator<PositionModel>() {
public PositionModel createFromParcel(Parcel in) {
return new PositionModel(in);
}
public PositionModel[] newArray(int size) {
return new PositionModel[size];
}
};
}
You're writing the lists out using the generic writeList method but reading them back using readTypedList call. These are not compatible. Check the documentation for readTypedList:
The list must have previously been written via writeTypedList(List) with the same object type.
Using a typed list allows the Parcel to have more efficient memory usage as it doesn't write the type of each object in the list into the stream. So if you try to read back list data as if it were written in "typed" but was instead written as a generic list, the parcel processing is getting unexpected data and causing it to throw up.

Categories

Resources