Getting items from parcelable array list - java

I'm having troubles with getting content from getParcelableArrayList.
I have data model class that extends parcelable
#DatabaseTable(tableName = "note")
public class Log implements Parcelable {
#DatabaseField(id = true, index = true)
UUID id;
#DatabaseField
String title;
#DatabaseField
String description;
public Log() {
}
#Override
public int describeContents() {
return 0;
}
public Log(Parcel in) {
this.title = in.readString();
this.description = in.readString();
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(title);
out.writeString(description);
}
public void readFromParcel(Parcel in){
title = in.readString();
description = in.readString();
}
public static final Parcelable.Creator<Log> CREATOR = new Parcelable.Creator<Log>(){
public Log createFromParcel(Parcel in){
return new FoodLog(in);
}
public Log[] newArray(int size){
return new FoodLog[size];
}
};
And I want make feature for editing entry in database.
I'm sending data from activity one to activity two via bundle like this
Activity one:
Intent intent = new Intent(LogList.this, AddLogActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("list", new ArrayList<>(mLog));
intent.putExtras(bundle);
startActivity(intent);
Receiving bundle via intent in Activity two:
Intent mIntent = getIntent();
if (mIntent != null) {
Bundle bundle = mIntent.getExtras();
if (bundle != null) {
mLogParcel = bundle.getParcelableArrayList("list");
}
}
So, my question is how to get data from passed arraylist in Activity two?
I have data saved inArrayList<Log> mLogParcel;, and I tried using readFromParcel on mLogParcel, but without positive results.
How to get data based on data model in this case?
Thanks a lot!

Related

Method getParcelableExtra() returns null when creating an intent

I have a problem regarding the creation of an intent and the handover of an object with the getParcelableExtra() method to it.
The aim of the project is the creation of a recycler view. If an item from the recycler is selected a new intent gets started and should display more detailed data.
Because the data is fetched from an external MySQL DB I'm using Volley for most of the networking stuff.
The recycler is implemented inside the Volley onResponse() method which is first called at app start (onCreate). Until this point everything works fine and the recycler is loaded and displayed correctly.
public class UserAreaActivity extends AppCompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_area);
initializeRecycler();
}
public void initializeRecycler() {
operations.getFoodFromDB(getFoodID(), new IDatabaseOperations() {
#Override
public void onSuccess(final ArrayList<Food> food_list) {
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mLayoutmanager = new LinearLayoutManager(UserAreaActivity.this);
mAdapter = new FoodAdapter(food_list);
mRecyclerView.setLayoutManager(mLayoutmanager);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new FoodAdapter.OnItemClickListener() {
#Override
public void OnItemClick(int position) {
Intent intent = new Intent(UserAreaActivity.this, FoodProfile.class);
GETS CORRECT OBJECT----->intent.putExtra("food", food_list.get(position));
startActivity(intent);
}
});
}
});
}
}
As you see I created an interface for the Volley onResponse method called onSuccess. Inside this method I am creating an onItemClickListener and this is where it gets ugly.
The onItemClickListener opens up the more detailed view of the item, but the method getParcelableExtra() returns NULL. Whatever I do it never returns an object of the class Food.
public class FoodProfile extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_food_profile);
Food food = getIntent().getParcelableExtra("food");<----RETURNS NULL
String price = food.getPrice();
String name = food.getName();
String rating = ((Float)food.getRating()).toString();
String imageRes = food.getmimgId();
TextView mPrice = (TextView) findViewById(R.id.Price);
mPrice.setText(price);
TextView mName = (TextView) findViewById(R.id.Name);
mName.setText(name);
TextView mRating = (TextView) findViewById(R.id.Rating);
mRating.setText(rating);
}
}
So the putExtra() works as intended and gets the correct object of the food class. But getParcelableExtra() returns NULL everytime. So no value is displayed in the started intent.
Food class:
public class Food implements Parcelable {
public int id;
public String name;
public String category;
public String date;
public int vegan;
public int vegetarian;
public String price;
public String uuid;
public float rating;
public String mimgId;
public Food(int id, String name, String category, int vegan, int vegetarian, String price, String uuid, float rating, String mimgId){
this.id = id;
this.name = name;
this.category = category;
this.date = date;
this.vegan = vegan;
this.vegetarian = vegetarian;
this.price = price;
this.uuid = uuid;
this.rating = rating;
this.mimgId = mimgId;
}
protected Food(Parcel in) {
id = in.readInt();
name = in.readString();
category = in.readString();
date = in.readString();
vegan = in.readInt();
vegetarian = in.readInt();
price = in.readString();
uuid = in.readString();
rating = in.readFloat();
mimgId = in.readString();
}
public static final Creator<Food> CREATOR = new Creator<Food>() {
#Override
public Food createFromParcel(Parcel in) {
return new Food(in);
}
#Override
public Food[] newArray(int size) {
return new Food[size];
}
};
public int getId() {
return id;
}
public String getName() {
if(name != null) {
name = name.replaceAll(System.getProperty("line.separator"), (""));
}
return name;
}
public String getDate() {
return date;
}
public int isVegan() {
return vegan;
}
public int isVegetarian() {
return vegetarian;
}
public String getPrice() {
return price;
}
public String getUuid() {
return uuid;
}
public float getRating(){return rating;}
public String getmimgId() {
return mimgId;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(price);
dest.writeString(name);
dest.writeString(((Float)rating).toString());
dest.writeString(mimgId);
}
}
Has anyone an idea whats causing the getParcelableExtra() to return null?
Thanks for your help in advance!
As I commented above, the writeToParcel() is problematic. The parcel should be written and read in the same order.
Please refer to the following pages as reference:
What is Parcelable in android
Using Parcelable
Understanding Androids Parcelable - Tutorial

How to pass a list from a class to an activity?

I declare a List object in a method of a java class, which gets filled with data inside this method. Now I want to pass the filled list to another activity. How should I do that?
if you are in a JAVA class and want to call the list in an Activity, them simply put the method return type as list and call it in the required Activity . Demo code is as follows
class ReturnList{
public List method(){
List list=new ArrayList();
return list;}
}
class ActivityDemo extends Activity{
onCreate(){
///activity code
ReturnList returnListObj=new ReturnList();
List listData= returnListObj.method();
//deal with list here
}}
First make your object class parcelable.
Pass data as a bundle
Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("data", yourObject);
intent.putExtras(bundle);
startActivity(intent);
Retrieving the data:
Bundle bundle = getIntent().getExtras();
yourObject = bundle.getParcelable("data");
Hope it helps :)
Define your class as below
public class CategoryEntity implements Parcelable{
public int id;
public String name;
public String imageOriginal;
public String imageThumb;
public String description;
public String status;
public String createdAt;
public String updatedAt;
public int imageDummy;
protected CategoryEntity(Parcel in) {
id = in.readInt();
name = in.readString();
imageOriginal = in.readString();
imageThumb = in.readString();
description = in.readString();
status = in.readString();
createdAt = in.readString();
updatedAt = in.readString();
imageDummy = in.readInt();
}
public static final Creator<CategoryEntity> CREATOR = new Creator<CategoryEntity>() {
#Override
public CategoryEntity createFromParcel(Parcel in) {
return new CategoryEntity(in);
}
#Override
public CategoryEntity[] newArray(int size) {
return new CategoryEntity[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeString(imageOriginal);
dest.writeString(imageThumb);
dest.writeString(description);
dest.writeString(status);
dest.writeString(createdAt);
dest.writeString(updatedAt);
dest.writeInt(imageDummy);
}
}
Pass your data using Bundle
startActivity(new Intent(CategoriesListingActivity.this, StoryDetailActivity.class)
.putExtra("List", your list with model class));
Handle your list in another activity
Bundle extra = getIntent().getExtras();
if (extra != null) {
storyList = (ArrayList<CategoryEntity>) extra.getParcelable("StoryListing");
}
Hope this will helps you.
Pass your list in intent.putExtra(), for example
Intent intent = new Intent(getApplicationContext() , YourNextActivity.class);
intent.putExtra("list" , (Serializable) yourList);
startActivity(intent);
and for retrieve list in NextActivity
Intent intent = getIntent();
intent.getSerializableExtra("list");

Problems with parcelable custom object - Android

I am trying to pass a custom object from one activity to another one.
I found that we can use a bundle to pass data into the intent and that we need a parcelable interface implemented in our class.
In the following code I removed the useless stuff.
public class TravelCard implements Parcelable {
public static final Creator<TravelCard> CREATOR = new Creator<TravelCard>() {
#Override
public TravelCard createFromParcel(Parcel in) {
return new TravelCard(in);
}
#Override
public TravelCard[] newArray(int size) {
return new TravelCard[size];
}
};
private String travelTitle, travelCountry, dateRange, numOfPerson;
private List<TravelDay> days;
protected TravelCard(Parcel in) {
travelTitle = in.readString();
travelCountry = in.readString();
dateRange = in.readString();
numOfPerson = in.readString();
in.readTypedList(days, TravelDay.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.travelTitle);
dest.writeString(this.travelCountry);
dest.writeString(this.dateRange);
dest.writeString(this.numOfPerson);
dest.writeTypedList(this.days);
}
In this class I have a List of another custom object:
public class TravelDay implements Parcelable {
public static final Creator<TravelDay> CREATOR = new Creator<TravelDay>() {
#Override
public TravelDay createFromParcel(Parcel in) {
return new TravelDay(in);
}
#Override
public TravelDay[] newArray(int size) {
return new TravelDay[size];
}
};
public int current_day;
private String title, note, dateOfToday;
protected TravelDay(Parcel in) {
title = in.readString();
note = in.readString();
dateOfToday = in.readString();
current_day = in.readInt();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(note);
dest.writeString(dateOfToday);
dest.writeInt(current_day);
}
I think until here everything should be fine.
In my activity :
Intent intent = new Intent(MainActivity.this, TravelDayActivity.class);
Bundle data = new Bundle();
data.putParcelable(DataKey.TRAVEL_CARD_BUNDLE,item);
intent.putExtras(data);
startActivity(intent);
And then in the TravelDayActivity :
Intent intent = getIntent();
Bundle data = intent.getExtras();
TravelCard travelCard = data.getParcelable(DataKey.TRAVEL_CARD_BUNDLE);
Every time I tried to access the TravelDayActivity the app stop running.
I used the debug mode to search something wrong but I did not find anything.
Thank you in advance
EDIT :
In the MainActivity that's how I get the item variable:
mAdapter = new TravelCardAdapter(travelCards, new TravelCardAdapter.OnItemClickListener() {
#Override
public void onItemClick(TravelCard item) {
Intent intent = new Intent(MainActivity.this,TravelDayActivity.class);
Bundle data = new Bundle();
data.putParcelable(DataKey.TRAVEL_CARD_BUNDLE,item);
intent.putExtras(data);
startActivity(intent);
}
});
Whenever I click on one of the recycler view item this code above is executed.
After the suggestion of #BVantur, I solved my problem using the parceler library :
parceler library
It has been very helpful, easy to use and a good documentation! I highly recommend it.

Extracting parcelable data in intent from calling activity takes long time

I was trying to pass a Parcelable data via Intent, but it took a long time trying to extract data from the bundle in the Intent.
Here's what I coded.
In the calling activity -
Parcelable objectTarget = xxx;
Intent intent = new Intent(this, TargetActivity.class);
intent.putExtra("data", objectTarget);
startActivity(intent);
In the target activity -
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// a --
Parcelable object = getIntent().getParcelableExtra("data");
// b --
}
And the a to b process surprisingly took 5000 milliseconds on a device and 700 on another without throwing a TransactionTooLargeException.
I measured the size of the 'objectTarget' by using 'GsonUtil.getInstance().toJson(value).getBytes().length;' and the printed result was 2273. So I'm guessing the object wasn't too big in size.
--
Also, here are some things I've tried
Bundle bundle = new Bundle();
bundle.putParcelable("data", objectTarget);
Parcelable passedObject = bundle.getParcelable("data");
And it took less than 2 milliseconds.
--
Parcelable objectTarget = xxx;
Intent intent = new Intent(this, TargetActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("data", objectTarget);
intent.putExtras(bundle);
startActivity(intent);
In the target activity -
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// a --
Bundle bundle = getIntent().getExtras();
Parcelable passedObject = bundle.getParcelable("data");
// b --
}
Of course the a to b process here took approx. the same time with slightly more overhead but I just wanted to give it a try.
--
Seems like it'd take a longer-than-expected time marshalling and unmarshalling when the parcelable data is put into an Intent and goes through 'startActivty(intent).'
I'm really at my wit's end and it'd be great if someone could shed some light on this issue. Thanks.
Create a class called ParcelabelUtil
import android.os.Parcel;
import android.os.Parcelable;
public class ParcelableUtil {
public static byte[] marshall(Parcelable parcelable) {
Parcel parcel = Parcel.obtain();
parcelable.writeToParcel(parcel, 0);
byte[] bytes = parcel.marshall();
parcel.recycle();
return bytes;
}
private static Parcel unmarshall(byte[] bytes) {
Parcel parcel = Parcel.obtain();
parcel.unmarshall(bytes, 0, bytes.length);
parcel.setDataPosition(0);
return parcel;
}
public static <T> T unmarshall(byte[] bytes, Parcelable.Creator<T> creator) {
Parcel parcel = unmarshall(bytes);
T result = creator.createFromParcel(parcel);
parcel.recycle();
return result;
}
}
N.B Make sure your object implements Parcelable and has a static field called CREATOR, which is an object implementing the Parcelable.Creator interface used to unmarshal or deserialize an object from Parcel. See example below
import android.os.Parcel;
import android.os.Parcelable;
public class MyObject implements Parcelable {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
private MyObject(Parcel in) {
setName(in.readString());
setAge(in.readInte())
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(getName());
parcel.writeString(getAge());
}
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];
}
};
In the calling activity
// create and initialize your object(MyObject)
Intent intent = new Intent(this, TargetActivity,class);
intent.putExtra("data", ParcelableUtil.marshall(your_object); // marshall the object and pass it as a byte[]
startActivity(intent);
In the called activity
byte[] objectBytes = getIntent().getExtras().getByteArray("data"); // get the object byte[]
MyObject object = Parcelable.unmarshall(objectBytes, MyObject.CREATOR); // unmarshall byte[]

How to pass array list using intent in android

How can i pass array list from one activity to another activity using intent.
From activity
ArrayList<ServicesInfo> bookedService = new ArrayList<ServicesInfo>();`
Intent intent = new Intent(getActivity() , Proceedtocart.class);
intent.putExtra("Listview",bookedService);
startActivity(intent);
To activity
bookedService = (ArrayList<BookedInfo>) getIntent().getSerializableExtra("Listview");
while running am getting error as "java.lang.runtimeexception parcel unable to marshal value android"
Help to to fix this issue
Try this :
Intent intent = new Intent(this, NextActivity.class);
intent.putStringArrayListExtra("Listview", bookedService);
startActivity(intent);
and on NextActivity :
yourArrayList = getIntent().getStringArrayListExtra("Listview");
You can use
public class ContactInfo {
private String name;
private String surname;
private int idx;
// get and set methods
}
public class ContactInfo implements Parcelable {
private String name;
private String surname;
private int idx;
// get and set method
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(surname);
dest.writeInt(idx);
}
// Creator
public static final Parcelable.Creator CREATOR
= new Parcelable.Creator() {
public ContactInfo createFromParcel(Parcel in) {
return new ContactInfo(in);
}
public ContactInfo[] newArray(int size) {
return new ContactInfo[size];
}
};
// "De-parcel object
public ContactInfo(Parcel in) {
name = in.readString();
surname = in.readString();
idx = in.readInt();
}
}
Put
Intent i = new Intent(MainActivity.this, ActivityB.class);
// Contact Info
ContactInfo ci = createContact("Francesco", "Surviving with android", 1);
i.putExtra("contact", ci);
Get
Intent i = getIntent();
ContactInfo ci = i.getExtras().getParcelable("contact");
tv.setText(ci.toString()); // tv is a TextView instance

Categories

Resources