29

I have an ArrayList of objects. ie ArrayList<ObjectName>.

I want to pass this to a new Activity. I tried to use putParcelableArrayList but it has issues with the object. I removed the <ObjectName> part from the creating of the variable and the method works but then I get eclipse complaining about unsafe stuff.

How do I pass this ArrayList<ObjectName> to a new Activity

Thanks for your time

EDIT I tried this :

ArrayList<ObjectName> arraylist = new Arraylist<ObjectName>();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("arraylist", arraylist);

I get the following Error:

The method `putParcelableArrayList(String, ArrayList<? extends Parcelable>)` in the type `Bundle` is not applicable for the arguments `(String, ArrayList<ObjectName>)`

EDIT2 Object Example Code. Do I need to changed this for Parcelable to work?

public class ObjectName {
    private int value1;
    private int value2;
    private int value3;

    public ObjectName (int pValue1, int pValue2, int Value3) {
        value1 = pValue1;
        value2 = pValue2;
        value3 = pValue3;
    }

    // Get Statements for each value below
    public int getValue1() {
        return value1;
    } 
    // etc
Boken
  • 4,825
  • 10
  • 32
  • 42
James Dudley
  • 915
  • 4
  • 15
  • 35

10 Answers10

49

Your object class should implement parcelable. The code below should get you started.

    public class ObjectName implements Parcelable {

    // Your existing code

        public ObjectName(Parcel in) {
            super(); 
            readFromParcel(in);
        }

        public static final Parcelable.Creator<ObjectName> CREATOR = new Parcelable.Creator<ObjectName>() {
            public ObjectName createFromParcel(Parcel in) {
                return new ObjectName(in);
            }

            public ObjectName[] newArray(int size) {

                return new ObjectName[size];
            }

        };

        public void readFromParcel(Parcel in) {
          Value1 = in.readInt();
          Value2 = in.readInt();
          Value3 = in.readInt();

        }
        public int describeContents() {
            return 0;
        }

        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(Value1);
            dest.writeInt(Value2);  
            dest.writeInt(Value3);
       }
    }

To use the above do this:

In 'sending' activity use:

ArrayList<ObjectName> arraylist = new Arraylist<ObjectName>();  
Bundle bundle = new Bundle();  
bundle.putParcelableArrayList("arraylist", arraylist);

In 'receiving' activity use:

Bundle extras = getIntent().getExtras();  
ArrayList<ObjectName> arraylist  = extras.getParcelableArrayList("arraylist");  
ObjectName object1 = arrayList[0];

and so on.

Mandel
  • 2,968
  • 2
  • 22
  • 19
  • how do you go about getting values from a parcelable after it has been created. not used one before. ie for Arraylist with objects it is value1=arrlist.getvalue1(); thanks – James Dudley Jul 13 '11 at 15:55
  • Sorry to be a pain. Currently I create a new object by "new ObjectName(value1, value2, value3)" and add it to the Arraylist. Using parcelables how do you create the ObjectName now. Thanks for your Time – James Dudley Jul 14 '11 at 12:53
  • @James Are you asking about how to retrieve the object in the receiving activity? I do not understand your question. – Mandel Jul 14 '11 at 13:18
  • You have shown above how to retrieve the object in the new activity. That is perfect. But how do I go about creating the ArrayList of ObjectName using parcelable instead of straight object class. Thanks – James Dudley Jul 14 '11 at 14:15
  • @James You create the arraylist of object name in the usual way. There is no 'parcelable' way of creating it. Once you have the arraylist you use the bundle to send it to the new activity using the code I showed above. – Mandel Jul 14 '11 at 15:38
  • The key (that I missed) was that you have to use ArrayList. You can't use the List interface: `List arraylist = new Arraylist();` – tir38 Aug 27 '16 at 23:10
  • Excellent Answer! – Christopher Smit Apr 04 '18 at 09:12
22

Very Easy way, try the following:

bundle.putSerializable("lstContact", (Serializable) lstObject);
lstObj = (List<Contacts>) bundle.getSerializable("lstContact");

and also you will need to implement your Contact class from Serializable interface. ex :

public class Contact implements Serializable{
   ...
   ...
   ...
}
noone
  • 6,168
  • 2
  • 42
  • 51
Manjeet Brar
  • 914
  • 1
  • 9
  • 27
14

You have two options:

Android passes Object in Bundle by serializing and deserializing (via Serializable or Parcelable). So all of your Objects you want to pass in a Bundle must implement one of those two interfaces.

Most Object serialize easily with Serializable and it is much simpler to implement Serializable and add a static UID to the class than to write all the methods/classes required for Parcelable.

dontocsata
  • 3,021
  • 3
  • 20
  • 19
2

You can pass your arraylist using Serializable interface. (Serialization is the process of converting an object into a stream of bytes in order to store the object or transmit it to memory, a database, or a file.)

public class ObjectName implements Serializable{
    private int Value1;
    private int Value2;
    private int Value3;

    public ObjectName (int pValue1, int pValue2, int Value3) {
        Value1 = pValue1;
        Value2 = pValue2;
        Value3 = pValue3;
    }

    // Get Statements for each value below
    public int getValue1() {
        return Value1;
    } 
    // etc
}

Now in your current activity

// here is the arrayList of yours
ArrayList<ObjectName> objNamesList = new ArrayList<>();
objNamesList.add(new ObjectName(1,1,1)); 
objNamesList.add(new ObjectName(2,2,2)); 
//intialize bundle instance
Bundle b = new Bundle();
//adding data into the bundle 
//key => objNames referece for the arrayList
//value => objNamesList , name of the arrayList 
//cast the arraylist into Serializable 
b.putSerializable("objNames", (Serializable) objNamesList);
//init the intent
Intent i = new Intent(CurrentActivity.this, NextActivity.class);
i.putExtras(b);
startActivity(i);

at next activity you will need to do as follows to get the arraylist

public class NextActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next_activity);
        // get the bundle
        Bundle b = getIntent().getExtras();
        ArrayList<ObjectName> q = (ArrayList<ObjectName>) b.getSerializable("objNames");
    }
}
noone
  • 6,168
  • 2
  • 42
  • 51
1

Looking at the documentation for putParcelableArrayList it looks like your ObjectName needs to extend the 'Parcelable' interface in order for this to work. The error you get seems to indicate this as well.

I would look here: http://developer.android.com/reference/android/os/Parcelable.html

Eugene S
  • 3,092
  • 18
  • 34
0

1) Make sure the object you want to parcel has correctly implemented Parcelable

2) Use this argument in putParcelableArrayList: new ArrayList<>(list)

Example:

    protected void onSaveInstanceState(Bundle outstate) {
        super.onSaveInstanceState(outstate);
        outstate.putParcelableArrayList("myObjects", new ArrayList<>(myListOfObjects));
    }
menk
  • 1
  • 1
0

what helped me was: setting all values while writing to the parcel. In case any value is NULL, I am setting deafult value for that particular property. Null values were getting set for few parameters, and thats why this error was being thrown.

Mabad
  • 439
  • 1
  • 4
  • 6
0

When I had to do that I simply put the ArrayList of objects into the extras bundle (it has to be an ArrayList, List is not Serializable apparently). Then all you have to do then is ensure the objects inside the list are serializable also.

Alexandru Cristescu
  • 3,898
  • 3
  • 19
  • 22
-1

I was struggling with same issue and found a much better approach of putting my array in Global Class that can be accessed across all activities. Thanks to this post for describing how to use global variables that can be accessed across multiple activities.

My global class is

public class GlobalClass extends Application{ public MyObject[] objArray }

Android Manifest Change

android:name=".GlobalClass"

Accessed in multiple activities as

GlobalClass g = (GlobalClass)getApplicationContext();
g.objArray[0].x = 100;
int x = g.objArray[0].x;

For Better understanding please go through the post.

Gailu
  • 111
  • 1
  • 11
-1

You can use a public static field in some of your classes.

See here for more advices.

Guillaume Brunerie
  • 4,676
  • 3
  • 24
  • 32
  • 1
    You could but it's rather discouraged: The android system can simply make the static fields be null without warning... there's plenty of warnings on the net about this: http://stackoverflow.com/questions/2475978/using-static-variables-in-android – Alexandru Cristescu Jul 13 '11 at 15:24
  • This is one of the proposed solution by the doc, so I don’t think this is discouraged. Most of the answers on your link says that static fields are OK (and nobody says that static fields can become null) – Guillaume Brunerie Jul 13 '11 at 15:42
  • Static fields are absolutely fine for final data; "public static final int WHATEVER = 0". The first time the class is accessed the static fields are initialised and remain until the class is unloaded. However, using static fields to pass data around is lazy and unsafe. Android has provided many mechanisms to achieve this. If it was as easy as dumping everything in static fields then classes like Bundle would have very little use. – protectedmember Mar 10 '17 at 08:56
  • This is discouraged.. Against the android's loosely coupled activity-fragment design paradigm – Samuel Robert Mar 15 '17 at 05:46