I'm having trouble passing an object via an Intent. I keep getting a null pointer error. here it is:
In my ListActivity:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(MyListActivity.this, DetailsActivity.class);
intent.putExtra("this_item", my_array.get(position));
startActivity(intent);
}
In the onCreate() of the DetailsActivity class:
thisItem = (MyObject) getIntent().getExtras().getParcelable("this_item");
System.err.println(thisItem.getDescription()); //<--Null pointer error!
The MyObject class does implement Parcelable. Why can't I pass this object over? I'm confused. Thanks for any help.
EDIT: Here is that class:
public class MyObject implements Comparable<MyObject>, Parcelable {
private Date date;
private MyType my_type;
private String description;
private int flags;
public MyObject(Date date, MyType type, String desc) {
this.date = date;
this.my_type = type;
this.description = desc;
}
public Date getDate() {return date;}
public MyType getMyType() {return my_type;}
public String getDescription() {return description;}
public int compareTo(MyObject another) {
if (getDate() == null || another.getDate() == null) {return 0;}
return getDate().compareTo(another.getDate());
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(flags);
}
public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
public MyObject createFromParcel(Parcel in) {
return new MyObject(in);
}
public MyObject[] newArray(int size) {
return new MyObject[size];
}
};
private MyObject (Parcel in) {
flags = in.readInt();
}
}
If you want to pass the data from one activity to another actiivty via intent the object must be parcelable or serializable in android..for parcelable you have to implement the serializable interface..for parcelable you must implement parcelable interface..
Write parcelable class like this..
parcel example
Related
I want to create and pass an object through intent to another activity, so I can process the object details in this activity and show it to the user.
This object is being identified by a value long.
I have an arraylist (releaseIds) which holds several long values of this object, so I just want to pass these values through an intent to the other activity.
The user can select the desired object from a alertdialog presenting this list, once he/she selects an item from this list the correct long ID is identified and a new object created and passed through intent.
But creating the new object somehow failes, because the object ReleaseModel is null in the receiving acitivity.
What I am doing wrong?
Creating and passing the object (ReleaseModel):
...
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
// Do something with the selection
for (int i = 0; i < releaseIds.size(); i++) {
if (i == item) {
long ID = releaseIds.get(i);
final ReleaseModel releaseModel = new ReleaseModel(ID);
ReleaseActivtiy_.intent(MyAppsMain.this).extra("releaseModel",
releaseModel).start();
}
}
}
});
...
The object itself:
public class ReleaseModel extends BaseModel {
private List<String> url = new ArrayList<>();
private boolean liked;
...
public ReleaseModel() {
}
public ReleaseModel(long id) {
super(id);
}
...
public void writeToParcel(Parcel parcel, int flags) {
super.writeToParcel(parcel, flags);
parcel.writeInt(liked ? 1 : 0);
...
}
public static final Parcelable.Creator<ReleaseModel> CREATOR = new Parcelable.Creator<ReleaseModel>() {
public ReleaseModel createFromParcel(Parcel in) {
return new ReleaseModel(in);
}
public ReleaseModel[] newArray(int size) {
return new ReleaseModel[size];
}
};
private ReleaseModel(Parcel parcel) {
super(parcel);
setLiked(parcel.readInt() == 1);
...
}
}
The basemodel:
public class BaseModel implements Parcelable {
private long id;
private long date;
...
public BaseModel() {
}
public BaseModel(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
...
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeLong(id);
parcel.writeLong(date);
...
}
public static final Parcelable.Creator<BaseModel> CREATOR = new Parcelable.Creator<BaseModel>() {
public BaseModel createFromParcel(Parcel in) {
return new BaseModel(in);
}
public BaseModel[] newArray(int size) {
return new BaseModel[size];
}
};
public BaseModel(Parcel parcel) {
setId(parcel.readLong());
setDate(parcel.readLong());
...
}
}
Receiving activity:
#EActivity(R.layout.release_activity)
public class ReleaseActivtiy extends BaseActivity implements LoaderManager
.LoaderCallbacks<BaseResponse>, NotificationCenter.NotificationCenterDelegate {
...
#Extra("releaseModel")
ReleaseModel releaseModel;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
#AfterViews
public void init() {
// Nullpointer exception on this line for releaseModel
String temp = releaseModel.getSubject().replaceAll("[^a-zA-Z]", "");
}
}
To pass ReleaseModel object to another Activity(ActivityPassedTo).
Do the Following Steps:
1.You Need to make ReleaseModel implements Serializable
2.To pass it to an Intent you need to have a Unique Key to identify the object passed in both the activities
Eg. you can create a Key:
static final String RELEASE_MODEL = "RELEASE_MODEL";
Now pass it to the activity in intent
Intent intent = new Intent(this,ActivityPassedTo.class);
intent.putExtra(RELEASE_MODEL,releaseModelObject);
startActivity(intent);
Now Retrieve the object in Activity (ActivityPassedTo)
Intent intent = getIntent()
ReleaseModel releaseModel = (ReleaseModel)intent.getSerializableExtra(RELEASE_MODEL);
I have a Parcelable object that has a list of Parcelable objects. I am trying to read that list back after it has been passed from one Activity to the next, but only the first element is "un-bundled"
public class MyBundle implements Parcelable {
private List<Data> dataList;
public static final Parcelable.Creator<MyBundle> CREATOR = new Parcelable.Creator<MyBundle>() {
public MyBundle createFromParcel(Parcel in) {
return new MyBundle(in);
}
public MyBundle[] newArray(int size) {
return new MyBundle[size];
}
};
public MyBundle() {
}
public MyBundle(Parcel in) {
//dataList = new ArrayList<>();
//in.readTypedList(dataList, Data.CREATOR);
dataList = in.createTypedArrayList(Data.CREATOR);
//BOTH have the same result
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
if (dataList != null && dataList.size() > 0) {
dest.writeTypedList(dataList);
}
}
}
The data object:
/*BaseObject has the following properties:
UUID uuid;
long databaseId;
createdDate;
modifiedDate;
*/
public class Data extends BaseObject implements Parcelable {
private String name;
private String serial;
private String location;
public Data() {}
private Data(Parcel in) {
String uuidString = in.readString();
if (uuidString == null) return; //this is null!
uuid = UUID.fromString(idString);
databaseId = in.readLong();
createdDate = new Date(in.readLong());
modifiedDate = new Date(in.readLong());
location = in.readString();
name = in.readString();
serial = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(uuid.toString());
dest.writeLong(databaseId);
dest.writeLong(createdDate.getTime());
dest.writeLong(modifiedDate.getTime());
dest.writeString(name);
dest.writeString(serial);
}
public static final Parcelable.Creator<Data> CREATOR
= new Parcelable.Creator<Data>() {
public Data createFromParcel(Parcel in) {
return new Data(in);
}
public Data[] newArray(int size) {
return new Data[size];
}
};
}
What I have tried:
Debugging - I can see the first element is read fine but the rest are return null, and they do have values when they are being written
"Android, How to use readTypedList method correctly in a Parcelable class?"
"how to properly implement Parcelable with an ArrayList?"
So this is the answer: My Data parcelable misses the location element when it creates the parcel. This obviously results in some kind of offset error when READING occurs. So the coded solution is as follows:
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(uuid.toString());
dest.writeLong(databaseId);
dest.writeLong(createdDate.getTime());
dest.writeLong(modifiedDate.getTime());
dest.writeString(location); /*HERE!*/
dest.writeString(name);
dest.writeString(serial);
}
I hope this helps someone else.
I've a custom parcelable (simplified) that contains a string array:
public class MyClass implements Parcelable {
public static final Creator<MyClass> CREATOR = new Creator<MyClass>() {
public MyClass createFromParcel(Parcel in) {
return new MyClass(in);
}
public MyClass[] newArray(int size) {
return new MyClass[size];
}
};
#SerializedName(“tips”)
private List<String> Tips;
public MyClass() {
Tips = new ArrayList<>();
}
protected Category(Parcel in) {
Tips = in.createStringArrayList();
}
public List<String> getTips() {
return Tips;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(Tips);
}
}
I'm trying to pass this parcelable via Intent to another activity. The process is VERY slow and sometimes I get an OOM exception...I don't understand why, I just want to pass a string array...
Save your array into database and pass id of that record.
I want to send my data from Activity1 to Activity2 with putExtra.
My Custom object implements Serializable :
public class ARObjectCategory implements Serializable {
private static final long serialVersionUID = 3128594851129501738L;
public int id;
public String name;
public transient ARObjectCategory parent;
public transient SparseArray<ARObjectCategory> children;
public transient Bitmap iconBitmap = null;
public String icon;
private boolean active = false;
public ARObjectCategory(int id, String name, ARObjectCategory parent) {
this.id = id;
this.name = name;
this.parent = parent;
this.children = new SparseArray<>();
}
public void addChild(ARObjectCategory child) {
children.append(child.id, child);
if (getActive())
child.setActive(true);
}
public final ARObjectCategory getChild(int index) {
return children.valueAt(index);
}
public final SparseArray<ARObjectCategory> getChildren() {
return this.children;
}
public final int getParentLast() {
ARObjectCategory parentTemp = this.parent;
while (parentTemp.parent != null) {
parentTemp = parentTemp.parent;
}
return parentTemp.id;
}
public final ARObjectCategory getChildById(int id) {
return children.get(id, null);
}
public final int getChildrenCount() {
return children.size();
}
public Boolean getActive() {
return this.active;
}
public void setActive(Boolean bool) {
this.active = bool;
}
public Bitmap getIconBitmap() {
return iconBitmap;
}
public void setIconBitmap(Bitmap iconBitmap) {
this.iconBitmap = iconBitmap;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
Activity1.java (Sender):
ARObjectCategory test1= adapter.getItem(position);
Intent subCat= new Intent(getActivity(), SubCategoriesActivity.class);
subCat.putExtra("test",test1);
subCat.putExtra("selected",position);
startActivity(subCat);
On Debug Mode my object looks ok. SpraseArray got object of AROjcectCategory.
Activity2.java (Reciever):
Bundle extras = getIntent().getExtras();
if (extras != null) {
int selected = extras.getInt("selected", -1);
ARObjectCategory list = (ARObjectCategory) extras.getSerializable("test");
SparseArray<ARObjectCategory> lista = list.getChildren();
}
But when i debug the Activity2. I see that my SpraseArray of children is null
Finally when i remove the transient from my objects.
public transient ARObjectCategory parent;
public transient SparseArray<ARObjectCategory> children;
I am getting the following error on my logcat :
java.lang.RuntimeException: Parcelable encountered IOException
writing serializable object (name =
com.ethos.ar.core.ARObjectCategory) ........
Caused by:
java.io.NotSerializableException: android.util.SparseArray ......
What is the correct way to send Object that has SpraseArray to other Activity.
Tip: Parcelable is not working:
dest.writeParcelable(this.children);
SparseArray<ARObjectCategory> cannot be converted to SparseArray<Object>
Thanks
When you use the transient modifier, that member is excluded from the serialization process. That's the reason you are getting a null object. When you remove the transient modifier then you receive an exception, but why? That's because the "SparseArray" object itself doesn't implement the "Serializable" interface. Remember that in order to an object be serializable then all of its attributes must implement the "Serializable" interface. Now what can you do? You should implement the "Parcelable" interface of Android, but how? If you have problems using the "SparseArray" in the parcelable process then you can parcel it to another object and the recreate the original "SparseArray" object in the creation process.
I have a class that contains data i want to pass it between intents, this class have arraylist that contains another class objects. this is my class
public class ParsedData implements Parcelable {
public String error;
public float protectionLevel;
public int protectionLevelColor;
public double lastBackup;
public boolean compressedType;
public Long driveFreeSpaceSize;
ArrayList<Item>Items = new ArrayList<Item>();
}
class Item {
public String name;
public float percentage;
public int files;
public long size;
}
how can i send this class between intents ?
you can let your class Item implements the Serializable interface, and use Intent.putExtra(String, Serializable). Since ArrayList implements also the Serializable interface, you can pass the whole Items object.
This may be your problem:
Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface.
Alternatively, I'd try to have Item implement Parcelable, as well.
The fail-safe alternative is to write your data structure into a JSON string, which also allows you to pass the data to other applications that don't have access to your ParsedData class.
You may take a look at Intent.putExtra(String name, Parcelable object) and implement the parcelable interface in your class.
i have found the answer after all. thanks all how helped me
this is the answer:
import android.os.Parcel;
import android.os.Parcelable;
public class ParsedData implements Parcelable {
public String error;
public float protectionLevel;
public int protectionLevelColor;
public double lastBackup;
public boolean compressedType;
public Long statusSendTime;
ArrayList<Item>Items = new ArrayList<Item>();
//---------------------Constructors---------------------------
public ParsedData() { ; };
public ParsedData(Parcel in) {
readFromParcel(in);
}
//------------------------------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(error);
dest.writeFloat(protectionLevel);
dest.writeInt(protectionLevelColor);
dest.writeDouble(lastBackup);
dest.writeByte((byte) (compressedType ? 1 : 0));
dest.writeLong(statusSendTime);
dest.writeList(Items);
}
private void readFromParcel(Parcel in) {
error = in.readString();
protectionLevel = in.readFloat();
protectionLevelColor = in.readInt();
lastBackup = in.readDouble();
compressedType =in.readByte() == 1;
statusSendTime = in.readLong();
in.readList(Items,Item.class.getClassLoader() );
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ParsedData createFromParcel(Parcel in) {
return new ParsedData(in);
}
public ParsedData[] newArray(int size) {
return new ParsedData[size];
}
};
}
class Item implements Parcelable {
public String name;
public float percentage;
//---------------------Constructors---------------------------
public Item() {
}
public Item(Parcel in) {
readFromParcel(in);
}
//------------------------------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeFloat(percentage);
}
public static final Creator<Item> CREATOR = new Creator<Item>() {
public Item createFromParcel(Parcel source) {
return new Item(source);
}
public Item[] newArray(int size) {
return new Item[size];
}
};
private void readFromParcel(Parcel in) {
this.name = in.readString();
this.percentage = in.readFloat();
}
}
and in the caller activity
ParsedData data = new PArsedData();
Intent intentBreakDown = new Intent(this,BreakDownBarActivity.class);
intentBreakDown.putExtra("data", data);
startActivity(intentBreakDown);
in the called activity(BreakDownBarActivity in my case)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.breakdownbar);
Bundle b = getIntent().getExtras();
ParsedData data = (ParsedData)b.getParcelable("data");
}