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[]
Related
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");
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.
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
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!
When I'm trying to pass an intent from one activity to another my app crashes, without the putExtra() it works fine.
Here's my snippet from the first activity
ArrayList<Subject> subjectList = new ArrayList<Subject>();
public void computeGrades(View view){
Intent intent = new Intent(this, JLCSActivity2B.class);
intent.putExtra("subjectList", subjectList);
startActivity(intent);
}
The Second Activity
public class JLCSActivity2B extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
Intent intent = getIntent();
ArrayList<Subject> subjectList = (ArrayList<Subject>) intent.getSerializableExtra("subjectList");
}
}
You need to implement Serializable in your Subject class.
public class Subject implements Serializable {
//your variables, constructor and getters and setters
}
In your Source Activity, use this :
ArrayList<Subject> subjectList = new ArrayList<Subject>();
Intent intent = new Intent(SourceActivity.this, TargetActivity.class);
intent.putExtra("subjectList", subjectList);
In your Target Activity, use this :
ArrayList<Subject> subjectList = new ArrayList<Subject>();
subjectList = (ArrayList<Question>)getIntent().getSerializableExtra("subjectList");
I hope it helps!
Implement your Subject class with Parcelable or Serializable
Android does not allow to pass objects between activities unless they implement Parcelable or Serializable. The fact that Parcelable is faster than Serialization makes it a preferred choice of approach while passing an object.
Example implementing Parcelable - http://wptrafficanalyzer.in/blog/android-parcelable-example-passing-data-between-activities/
Parcelable Vs Serializable - http://www.3pillarglobal.com/insights/parcelable-vs-java-serialization-in-android-app-development
You can extend your entity class with serializable or better than seriablizable with parcelable interface.
You should implement parcelable interface in your Subject entity
public class Subject implements Parcelable {
String parceldata;
// your other fields with getter & setters
public Subject(Parcel in) {
String[] data = new String[1];
in.readStringArray(data);
this.parceldata = data[0];
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Subject createFromParcel(Parcel in) {
return new Subject(in);
}
public Subject[] newArray(int size) {
return new Subject[size];
}
};
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
}
}
for sending
args.putParcelable("data", subjectlist);
and to access
subjectlist = (ArrayList<Subject>) getArguments().getParcelable("data");
hope this will help you..