How to Send Objects Through Bundle

How to send objects through bundle

Figuring out what path to take requires answering not only CommonsWare's key question of "why" but also the question of "to what?" are you passing it.

The reality is that the only thing that can go through bundles is plain data - everything else is based on interpretations of what that data means or points to. You can't literally pass an object, but what you can do is one of three things:

1) You can break the object down to its constitute data, and if what's on the other end has knowledge of the same sort of object, it can assemble a clone from the serialized data. That's how most of the common types pass through bundles.

2) You can pass an opaque handle. If you are passing it within the same context (though one might ask why bother) that will be a handle you can invoke or dereference. But if you pass it through Binder to a different context it's literal value will be an arbitrary number (in fact, these arbitrary numbers count sequentially from startup). You can't do anything but keep track of it, until you pass it back to the original context which will cause Binder to transform it back into the original handle, making it useful again.

3) You can pass a magic handle, such as a file descriptor or reference to certain os/platform objects, and if you set the right flags Binder will create a clone pointing to the same resource for the recipient, which can actually be used on the other end. But this only works for a very few types of objects.

Most likely, you are either passing your class just so the other end can keep track of it and give it back to you later, or you are passing it to a context where a clone can be created from serialized constituent data... or else you are trying to do something that just isn't going to work and you need to rethink the whole approach.

How to pass custom object in Bundle?

One way is to have your custom object implement the Parcelable interface and use Bundle.putParcelable/Bundle.getParcelable

How to send an object from one Android Activity to another using Intents?

the most easiest solution i found is..
to create a class with static data members with getters setters.

set from one activity and get from another activity that object.

activity A

mytestclass.staticfunctionSet("","",""..etc.);

activity b

mytestclass obj= mytestclass.staticfunctionGet();

How to pass an object from one activity to another on Android

One option could be letting your custom class implement the Serializable interface and then you can pass object instances in the intent extra using the putExtra(Serializable..) variant of the Intent#putExtra() method.

Actual Code:

In Your Custom Model/Object Class:

public class YourClass implements Serializable {

At other class where using the Custom Model/Class:

//To pass:
intent.putExtra("KEY_NAME", myObject);

myObject is of type "YourClass".
Then to retrieve from another activity, use getSerializableExtra
get the object using same Key name. And typecast to YourClass is needed:

// To retrieve object in second Activity
myObject = (YourClass) getIntent().getSerializableExtra("KEY_NAME");

Note: Make sure each nested class of your main custom class has implemented Serializable interface to avoid any serialization exceptions. For example:

class MainClass implements Serializable {

public MainClass() {}

public static class ChildClass implements Serializable {

public ChildClass() {}
}
}

Send object from Activity to Fragment using Bundle

Both MyProfile and Employee don't implement Parcelable

The hard way: Make your classes implement Parcelable as per the documentation.

The easy way: Add this lib. That will auto generate that for you. Will just need to do

bundle.putParcelable("myProfile", Parcels.wrap(myProfile));
bundle.putParcelable("employee", Parcels.wrap(employee());

MyProfile myProfile = Parcels.unwrap(getArguments().getParcelable("myProfile"));
Employee employee = Parcels.unwrap(getArguments().getParcelable("employee"));

and add the @Parcel annotation on your classes:

@Parcel
public class MyProfile{//rest of the normal code}

@Parcel
public class Employee{//rest of the normal code}

Is it possible to pass an array of Objects through a bundle?

Basically we have a couple of options here.

Option 1 is to use Activity.onSaveInstanceState() method. There you store everything into an instance of Bundle class. Bundle requires simple, parcelable or serializable types. You can pass arrays too, but these must be arrays of those types.

Option 2 would be to override Activity.onRetainCustomNonConfigurationInstance() and return your array from there. New instance of this activity can retrieve this array by calling Activity.getLastNonConfigurationInstance(). Although this option works fine, it is already deprecated. This is where 3rd option comes into play.

Option 3 is to use a retained Fragment. Here the idea is to create a Fragment and to call Fragment.setRetaineInstance(true) in either onCreate() or onCreateView() of this fragment. Once called, this fragment becomes "retained". If you rotate your device, then new activity instances will be created with every new rotation, but the same instance of retained fragment will be passed to every new instance of the activity. If you keep your array there, it will be available in every new activity instance instantly. This would be a way to go.

I would like to note, that option 1 is persisted. If your app goes into background and Android kills it and later starts again, you will have your array delivered to onCreate(Bundle savedInstanceState). In contrast to this, options 2 and 3 will lose the state. If you can re-create your array every time activity is created, you can go with option 2 or 3.

Passing a custom Object from one Activity to another Parcelable vs Bundle

Parcelable and Bundle are not exclusive concepts; you can even deploy both on your app at a time.

[1] Term Parcelable comes with Serialization concept in Java (and other high-level language such as C#, Python,...). It ensures that an object - which remains in RAM store - of such Parcelable class can be saved in file stream such as text or memory (offline status) then can be reconstructed to be used in program at runtime (online status).

In an Android application, within 2 independent activities (exclusively running - one starts then other will have to stop):

There will be NO pointer from current activity to refer to previous one and its members - because previous activity is stopped and cleared out form memory; so that to maintain object's value passed to next activity (called from Intent) the object need to be parcelable (serializable).

[2] While Bundle is normally the Android concept, denotes that a variable or group of variables. If look into lower level, it can be considered as HashMap with key-value pairs.

Conclusion:

  • Bundle is to store many objects with related keys, it can save any object in native types, but it doesn't know how to save a complex object (which contains an ArrayList for example)

  • Parcelable class is to ensure a complex instance of it can be serialized and de-serialized during runtime. This object can contains complex types such as ArrayList, HashMap, array, or struct,...

[UPDATED] - Example:

//Class without implementing Parcelable will cause error 
//if passing though activities via Intent
public class NoneParcelable
{
private ArrayList<String> nameList = new ArrayList<String>();
public NoneParcelable()
{
nameList.add("abc");
nameList.add("xyz");
}
}

//Parcelable Class's objects can be exchanged
public class GoodParcelable implements Parcelable
{
private ArrayList<String> nameList = new ArrayList<String>();
public GoodParcelable()
{
nameList.add("Can");
nameList.add("be parsed");
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
// Serialize ArrayList name here
}
}

In source activity:

NoneParcelable nonePcl = new NoneParcelable();
GoodParcelable goodPcl = new GoodParcelable();
int count = 100;

Intent i = new Intent(...);
i.putExtra("NONE_P",nonePcl);
i.putExtra("GOOD_P",goodPcl);
i.putExtra("COUNT", count);

In destination activity:

Intent i = getIntent();

//this is BAD:
NoneParcelable nP = (NoneParcelable)i.getExtra("NONE_P"); //BAD code

//these are OK:
int count = (int)i.getExtra("COUNT");//OK
GoodParcelable myParcelableObject=(GoodParcelable)i.getParcelableExtra("GOOD_P");// OK

How to insert non-parceable and non-serializable object into Bundle

You can't. All you can do is take the information from it, create your own object that is Parcelable or Serializable, and send that.



Related Topics



Leave a reply



Submit