Writing data with Parcel Object - java

I am having some hard time trying to figure out how to write data with a Parcel object, I am new using this class and I've been doing some research but don't understand how to, here is the parcelable class
public class Item implements Parcelable {
private String iItemName;
private String iType;
private String iSerial;
private String iRetailer;
private String iLocation;
private String iValue;
private String iDescription;
public Item() {
super();
}
public Item (Parcel in) {
super();
this.iItemName = in.readString();
this.iType = in.readString();
this.iSerial = in.readString();
this.iRetailer = in.readString();
this.iLocation = in.readString();
this.iValue = in.readString();
this.iDescription = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(getItemName());
parcel.writeString(getType());
parcel.writeString(getSerial());
parcel.writeString(getRetailer());
parcel.writeString(getLocation());
parcel.writeString(getValue());
parcel.writeString(getDescription());
}
public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>(){
#Override
public Item createFromParcel(Parcel source) {
Item item = new Item();
item.iItemName = source.readString();
return item;
}
public Item [] newArray(int size) {
return new Item[size];
}
};
public String getItemName() {
return iItemName;
}
public void setItemName(String iItemName) {
this.iItemName = iItemName;
}
my question is if I want to create a new Item object I need to send as a parameter a Parcel Object am I right? so I can do something like:
String name = getString("name");
// how to add name to the parcel object?
Parcel parcel;
Item i = new Item(parcel);

No you do not need to. Your object now has two constructors. You should create the object like normal and call its setter methods. You should avoid manually creating parcels and rather use writeValue() and readValue() methods.
// Create an item as usual
Item myItem = new Item();
myItem.setItemName("name");
// Add it to a parcel
Parcel parcel = Parcel.obtain();
parcel.writeValue(myItem);
// Read the item back from the parcel
parcel.setDataPosition(0);
Item newItem = (Item) parcel.readValue(Item.class.getClassLoader());
// When you are finished with the parcel
parcel.recycle();
Usually you would create an object from a Parcel when receiving it from an Intent. In which case you would do the following.
// Create intent
Intent intent = new Intent(this, MyActivity.class);
Bundle itemBundle = new Bundle();
itemBundle.putParcelable("item_extra", myItem);
intent.putExtras(itemBundle);
startActivity(intent);
// In the activities onCreate(Bundle savedInstanceState)
Item myItem = getIntent().getParcelableExtra("item_extra");

Related

Parcelable object changes completely when sent as an Extra of an Intent

I'm trying to put a Parcelable object as an extra in an intent and pass it to the next Activity, and it doesn't crash but the object changes dramatically. I'm sending when clicking on an item from a RecyclerView in a Fragment and opening an Activity from it.
This is how I send it:
AdminProfile adminProfile = list.get(position).admin;
Intent intent = new Intent(view.getContext(),ClosedChatActivity.class);
intent.putExtra("chat",adminProfile);
view.getContext().startActivity(intent);
This how I get it:
adminProfile = (AdminProfile) getIntent().getExtras().getParcelable("chat");
And here the class:
public class AdminProfile implements Parcelable {
public static final Creator<AdminProfile> CREATOR = new Creator<AdminProfile>() {
#Override
public AdminProfile createFromParcel(Parcel in) {
return new AdminProfile(in);
}
#Override
public AdminProfile[] newArray(int size) {
return new AdminProfile[size];
}
};
public Long idUser;
public String name;
public String professio;
public String description;
public List<WebLink> webLinks;
public Long idOficina;
protected AdminProfile(Parcel in) {
if (in.readByte() == 0) {
idUser = null;
} else {
idUser = in.readLong();
}
name = in.readString();
professio = in.readString();
description = in.readString();
webLinks = in.createTypedArrayList(WebLink.CREATOR);
if (in.readByte() == 0) {
idOficina = null;
} else {
idOficina = in.readLong();
}
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeLong(idUser);
parcel.writeString(name);
parcel.writeString(professio);
parcel.writeString(description);
parcel.writeLong(idOficina);
parcel.writeList(webLinks);
}
}
I can't understand why, but when I send the object I have UserId=3, but when I get it it's userId=55834574848. Any ideas?
The Parcelable functions were filled automatically by Android Studio, and reading the first byte messed it up.
Changing
if (in.readByte() == 0) {
idUser = null;
} else {
idUser = in.readLong();
}
for
idUser = in.readLong();
fixed it.

How to pass object with List of other object between activities using Parcelable?

I have an object called Order which I want to pass between activities. Currently I am using Parcelable to do so.
public class Order implements Parcelable {
private String email;
private Long timestamp;
private List<OrderItem> items;
public Order() { }
private Order(Parcel in) {
email = in.readString();
timestamp = in.readLong();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(email);
if (timestamp == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeLong(timestamp);
}
dest.writeTypedList(items);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<Order> CREATOR = new Creator<Order>() {
#Override
public Order createFromParcel(Parcel in) {
return new Order(in);
}
#Override
public Order[] newArray(int size) {
return new Order[size];
}
};
// Getters
...
}
The items field is a List of OrderItem objects which implement the Parcelable interface.
public class OrderItem implements Parcelable {
private String orderedClothingId;
private int quantity;
public OrderItem() { }
public OrderItem(String orderedClothingId, int quantity) {
this.orderedClothingId = orderedClothingId;
this.quantity = quantity;
}
private OrderItem(Parcel in) {
orderedClothingId = in.readString();
quantity = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(orderedClothingId);
dest.writeInt(quantity);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<OrderItem> CREATOR = new Creator<OrderItem>() {
#Override
public OrderItem createFromParcel(Parcel in) {
return new OrderItem(in);
}
#Override
public OrderItem[] newArray(int size) {
return new OrderItem[size];
}
};
}
Now to pass an Order object called order from one activity to another I do the following:
Intent intent = new Intent(mContext, ActivityTwo.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(ORDER_DETAIL_INTENT_EXTRA_KEY, order);
mContext.startActivity(intent);
In ActivityTwo I collect the Order object like so:
Bundle data = getIntent().getExtras();
assert data != null;
mOrder = data.getParcelable(ORDER_DETAIL_INTENT_EXTRA_KEY);
However, when I log the items field contained in the Order object in ActivityTwo it is null. How do I pass the original non-null Order object between activities without the items list being null?
First you miss to read the array back with dest = in.readTypedList(emptyList, CREATOR);
But second and more important, you need to write/read the same ammount of arguments, since you have a if in your writeToParcel you need the same when reading:
private Order(Parcel in) {
email = in.readString();
if(in.readByte() == 1)
timestamp = in.readLong(); //here to skip just like the writeToParcel
in.readTypedList(items = new ArrayList<OrderItem>(), OrderItem.CREATOR);
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(email);
if (timestamp == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeLong(timestamp);
}
dest.writeTypedList(items);
}
From first glance it looks like you are passing different different keys within your parcelable
ORDER_DETAIL_INTENT_EXTRA_KEY in the first and CLOTHING_ADMIN_DETAIL_INTENT_EXTRA_KEY in the 2nd. They should both be the same, so pick which one.
Also you can use getIntent().getParcelableExtra() instead of having to use a Bundle

How to initialize arraylist which store in a Pojo class in another activity?

I want to store the data in a ArrayList and access it in another class,but when when I access the arraylist,the arraylist.size() is 0.Means I didn't access the same arraylist. Somebody please tell me what I doing wrong.
Here is my POJO class
public class item {
private String name;
private String body;
private String profileImage;
public Item(){
}
public Item(String body,String name,String profileImage){
this.body = body;
this.name = name;
this.profileImage = profileImage;
}
//Getter and setter
Here is how I store the data in Class A,which I checked,is successfully insert it to the arraylist.
Class A
List<Item> items = new ArrayList<>();
Item item = new Item();
item.setBody(body);
item.setName(name);
item.setProfileImage(profileImage);
items.add(item);
The problem is in Class B when I access the item.size() it return value 0,means that I didnt access to the same arraylist.
Here is what I done in Class B
List<Item>items = new ArrayList<>();
Log.d("ListSize",String.valueOf(items.size()));
I tried this which I done in RecycleView before,but this doesnt work,cause my Class B is a Fragment activity
public Class B(Context mContext, List<Item> items) {
this.mContext = mContext;
this.items = items;
}
So what is the correct way for me initialize the arraylist which I save data to in Class A in Class B?
change class like this:
public class Item implements Parcelable{
private String name;
private String body;
private String profileImage;
public Item(){
}
public Item(Parcel in) {
name = in.readString();
body = in.readString();
profileImage = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(body);
dest.writeString(profileImage);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>() {
#Override
public Item createFromParcel(Parcel in) {
return new Item(in);
}
#Override
public Item[] newArray(int size) {
return new Item[size];
}
};
public Item(String body,String name,String profileImage){
this.body = body;
this.name = name;
this.profileImage = profileImage;
}
Now in Class A:
ArrayList<Item> mDATA = new ArrayList<>();
/****** add values in array list ****/
Intent i = new Intent(CLASS_A.this, CLASS_B.class);
i.putParcelableArrayListExtra("ARRAY_DATA", mDATA);
startActivity(i);
Now in Class B, get list:
Intent intent = getIntent();
ArrayList<Item> mDATAFROMA = new ArrayList<>();
try {
mDATAFROMA = intent.getParcelableArrayListExtra("ARRAY_DATA");
Log.d("ListSize",String.valueOf(mDATAFROMA.size()));
} catch (Exception e) {
e.printStackTrace();
}
For fragement pass like:
Bundle args = new Bundle();
args.putParcelableArrayList("GET_LIST", (ArrayList<? extends Parcelable>) mDATA);
fragmentDemo.setArguments(args);
And in fragment fetch:
ArrayList<Item> mDATAFROMA = new ArrayList<>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle pb=getArguments();
mDATAFROMA = pb.getParcelableArrayList("GET_LIST");
}

Why won't my user-defined object construct?

I have an Parcelable object called Book and another called Author. I can't tell why the object constructor for Book is not working. The first bit of code is where i try to make it so I can send it to a parent activity. The values were checked before, and when I do the .toString() method on book, I get null Price: null
Activity Code
EditText editText = (EditText) findViewById(R.id.search_title);
String title = editText.getText().toString();
editText = (EditText) findViewById(R.id.search_author);
String author = editText.getText().toString();
editText = (EditText) findViewById(R.id.search_isbn);
int isbn = Integer.parseInt(editText.getText().toString());
...
Parcel p = Parcel.obtain();
p.writeInt(isbn);
p.writeString(title);
p.writeString(author);
p.writeString(editText.getText().toString());
p.writeString("$15.00");
Intent intent = new Intent();
Book book = new Book(p);
System.out.println(book.toString());
Book.java
public class Book implements Parcelable {
private int id;
private String title;
private ArrayList<Author> authors = new ArrayList<Author>();
//private int Aflags;
private String isbn;
private String price;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(id);
out.writeString(title);
out.writeTypedList(authors);
out.writeString(isbn);
out.writeString(price);
}
public Book(Parcel in) {
id = in.readInt();
title = in.readString();
in.readTypedList(authors, Author.CREATOR);
isbn = in.readString();
price = in.readString();
}
public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {
public Book createFromParcel(Parcel in) {
return new Book(in);
}
public Book[] newArray(int size) {
return new Book[size];
}
};
#Override
public String toString()
{
return title + " Price: " + price;
}
}
Author.java
public class Author implements Parcelable {
// NOTE: middleInitial may be NULL!
public String firstName;
public String middleInitial;
public String lastName;
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(firstName);
if (middleInitial.length() == 0)
out.writeString(middleInitial);
out.writeString(lastName);
}
private Author(Parcel in)
{
firstName = in.readString();
if (in.dataSize() == 2)
middleInitial = in.readString();
if (in.dataSize() == 1)
lastName = in.readString();
}
public static final Parcelable.Creator<Author> CREATOR = new Parcelable.Creator<Author>() {
public Author createFromParcel(Parcel in) {
return new Author(in);
}
public Author[] newArray(int size) {
return new Author[size];
}
};
#Override
public int describeContents() {
return 0;
}
}
Parcel p = Parcel.obtain();
p.writeInt(isbn);
p.writeString(title);
p.writeString(author); // Here i think u need to write list of author and not string
p.writeString(editText.getText().toString());
p.writeString("$15.00");
Intent intent = new Intent();
Book book = new Book(p);
System.out.println(book.toString());
/*****Edited answer ******/
//HERE u go mate this should work, tested code
//You need to parse the author text then
Parcel p = Parcel.obtain();
p.writeInt(23); // isbn
p.writeString("sometitle");
// List<String> data = new List<String>();//parseAuthor(author); // function dependent on what u get
Parcel auth = Parcel.obtain();
auth.writeString("firstname"); // firstname
auth.writeString("middle"); // middle
auth.writeString("lastname"); // lastname
auth.setDataCapacity(3);
auth.setDataPosition(0);
Author a = Author.CREATOR.createFromParcel(auth);
ArrayList<Author> authors = new ArrayList<Author>();
authors.add(a);
p.writeTypedList(authors);
p.writeString("something");
p.writeString("$15.00");
p.setDataPosition(0);
Intent intent = new Intent();
Book book = Book.CREATOR.createFromParcel(p);
System.out.println(book.toString());
Hi so I just gave up and made a new constructor that doesn't use Parcels.
But what was written below p.setDataPosition(0); may work as well for future users

Cannot access my Parcelable objects methods

I have passed my object using Parcelable to the new activity, and also written into the writeToParcel. I believe that the object has been transferred, as i can use .toString() however it has none of its associated methods. i used this link: http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/ my code runs, however I was expecting to be able to use a.clubName() or some such to be able to access these details, either i'm trying to access the details incorrectly or I have not quite got the set up correct.
Thanks for any help.
This is my Clubs class that associates the details to the parcel
public class Clubs implements Parcelable{
//lots of variables defining things such as clubName, address etc.
public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){
public Clubs createFromParcel(Parcel in) {
return new Clubs(in); }
public Clubs[] newArray(int size) {
return new Clubs[size]; }
};
private void readFromParcel(Parcel in) {
clubName = in.readString();
address = in.readString();
postcode = in.readString();
contactName = in.readString();
contactPhone = in.readString();
date = in.readString();
eventType = in.readString();
scrutTime = in.readString();
startTime = in.readString();
eventName = in.readString();
week = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(clubName);
dest.writeString(address);
dest.writeString(postcode);
dest.writeString(contactName);
dest.writeString(contactPhone);
dest.writeString(date);
dest.writeString(eventType);
dest.writeString(scrutTime);
dest.writeString(startTime);
dest.writeString(eventName);
dest.writeString(week);
}
public Clubs(Parcel in) { readFromParcel(in); }
This is my onItemClick method that starts the new activity that should send the object across
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
Clubs mymeeting = db.get(map.get(position));
Intent i = new Intent(ListSample.this, DynamicEvents.class);
i.putExtra("mymeeting", mymeeting);
startActivity(i);
}
});
this is the class i want to be able to write the details into
public class DynamicEvents extends Activity
{
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(20);
Object a = b.getParcelable("mymeeting");
textView.setText(a.toString());
// Set the text view as the activity layout
setContentView(textView);
}
}
You need to cast the parcelable to the correct class type.
Parcelable parcelable = b.getParcelable("mymeeting");
if(parcelable instanceof Clubs) {
Clubs clubs = (Clubs) parcelable;
}

Categories