17

I am trying to pass LinkedHashMap between activities, my code is like this

Activity A

LinkedHashMap mLinkedHashMap = new LinkedHashMap<String, Object>();
// setting data in map
Bundle bundle = new Bundle();
bundle.putSerializable("OBJECTS_LINKED_HASHMAP", mLinkedHashMap);  
Intent intent = new Intent(this, ActivityB.class); 
intent.putExtras(bundle);
startActivity(intent);

in Activity when I receive bundle object I am getting "Class cast exception" error message

Activity B

Bundle bundle = this.getIntent().getExtras();
LinkedHashMap mLinkedHashMap = new LinkedHashMap<String, Object>();
mLinkedHashMap = (LinkedHashMap<String, Object>) bundle.getSerializable("OBJECTS_LINKED_HASHMAP");

Getting class cast exceptions

ClassCastException: java.util.HashMap cannot be cast to LinkedHashMap

I have checked documentation LinkedHashMap also implementing Serializable interface.

I am using LinkedHashMap because I want to maintain object order, they way they inserted I want back in order.

How to pass LinkedHashMap between activities ?

Mac
  • 1,153
  • 2
  • 20
  • 34
  • You cannot reliably insert/extract a `LinkedHashMap` to/from an `Intent` because Android converts the `LinkedHashMap` to a `HashMap` when serializing the `Map` to the `Bundle` in the `Intent`. On the receiving end you get a `HashMap` and the ordering of the `LinkedHashMap` is gone. You need to convert the `LinkedHashMap` to an ordered array and pass that in the `Intent`, or use another serialize/deserialize mechanism. IMHO adding a GSON library to do this is overkill, but there are other more performant choices. – David Wasser Aug 15 '16 at 18:42
  • See http://stackoverflow.com/questions/12300886/linkedlist-put-into-intent-extra-gets-recast-to-arraylist-when-retrieving-in-nex/12305459#12305459 for more gory details – David Wasser Aug 15 '16 at 18:42

5 Answers5

22

Try GSON for change :)

Download gson.jar from this link

And add gson-2.2.2.jar file in your project.
Now pass your LinkedHashMap to another activity using GSON

like this(modified this below code as per your need):

MainActivity:::

public class MainActivity extends Activity {
    ObjectClass obj=new ObjectClass();
    LinkedHashMap<String, ObjectClass> mLinkedHashMap = new LinkedHashMap<String, ObjectClass>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        obj.id=1;
        obj.name="hello";

        mLinkedHashMap.put("test", obj);

        Gson gson = new Gson();
        String list = gson.toJson(mLinkedHashMap); 
        Intent intent = new Intent(this, secondActivity.class); 
        intent.putExtra("list", list);
        startActivity(intent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

secondActivity:::

public class secondActivity extends Activity {
    LinkedHashMap<String, ObjectClass> mLinkedHashMap = new LinkedHashMap<String, ObjectClass>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
     String str=  getIntent().getStringExtra("list");
     Gson gson = new Gson();

     Type entityType = new TypeToken< LinkedHashMap<String, ObjectClass>>(){}.getType();
     mLinkedHashMap = gson.fromJson(str, entityType);
    ObjectClass obj = mLinkedHashMap.get("test");

     Log.i("list", ""+obj.id);
    }
}

Worked for me. Hope this will help.

And Here is my object class for reference.

public class ObjectClass {

    public int id;
    public String name;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }


}

How to add gson-2.2.2.jar file.

1) copy your gson-2.2.2.jar from downloaded folder "google-gson-2.2.2" .
2) paste it to your project's asset folder.
3) now go to your project buildpath by right clicking on the your project>Build Path>Configure Build Path..
4) It will open one dialog select java build path from right menu and go to library tag then
Click on "Add Jars..." button as you can see in below image
it will open another dialog to add jar. here select the gson-2.2.2.jar that we added in project's asset folder(step 2).
It will add jar to your project(I already added it in my project as you can see in below image)

enter image description here 5)Now select Order and Export tag and select your gson-2.2.2.jar(see below image).
enter image description here 6)Press OK and now you can use GSON in your project

KDeogharkar
  • 10,939
  • 7
  • 51
  • 95
  • On Android, this is a bad idea. Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly. – Manish Dubey Feb 16 '13 at 09:12
  • Without a JIT, direct field access is about 3x faster than invoking a trivial getter. With the JIT (where direct field access is as cheap as accessing a local), direct field access is about 7x faster than invoking a trivial getter. This is true in Froyo, but will improve in the future when the JIT inlines getter methods. – Manish Dubey Feb 16 '13 at 09:12
  • @ManishAndroid and for Pragnani, I am agree with you, I have tried your solution but I was getting ClassCastException as bundle always returns Hashmap object only, I am not getting how its working for you ? can you please update your answer with full code like how you are declaring Linked Hashmap and how you are passing and receiving it ? Thanks for your valuable suggestion. – Mac Feb 17 '13 at 14:58
  • hello, how to convert to linkedhashmap in kotlin? Thanks – famfamfam Sep 16 '20 at 10:42
4

A LinkedHashMap<> is not Parcelable or Serializable

EDIT :

Check this :

serialize/deserialize a LinkedHashMap (android) java

Community
  • 1
  • 1
Manish Dubey
  • 4,206
  • 8
  • 36
  • 65
3

Edit:

Based on the link provided by Manish Android the solution is

  if (getIntent().getSerializableExtra("OBJECTS_LINKED_HASHMAP") != null)
                HashMap<?, ?>   user_info = (HashMap<?, ?>) getIntent().getSerializableExtra("OBJECTS_LINKED_HASHMAP");


    LinkedHashMap<String, Object>   userdata= (LinkedHashMap<String, Object>) user_info

You need to get the like this

if (getIntent().getSerializableExtra("OBJECTS_LINKED_HASHMAP") != null)
        LinkedHashMap<String, Object>   user_info = (LinkedHashMap<String, Object>) getIntent().getSerializableExtra("OBJECTS_LINKED_HASHMAP");
Pragnani
  • 20,075
  • 6
  • 49
  • 74
  • 1
    there no problem with "null" getIntent().getSerializableExtra("OBJECTS_LINKED_HASHMAP"); is not returning LinkedHashMap object, instead of that its returning HashMap object, and because of that I am getting ClassCastException – Mac Feb 16 '13 at 06:12
  • @Mac : which value u are passing in place of Object ? if any custom class object then class must implement Serializable interface – ρяσѕρєя K Feb 16 '13 at 06:14
  • @ρяσѕρєяK Yes my Object class implemening Serializable interface. – Mac Feb 16 '13 at 06:22
  • @Mac please refer to the link provided by Manish Android, this will solve your problem – Pragnani Feb 16 '13 at 06:30
  • @Pragnani i am facing same issue can you please post your sending intent code along with variable initialization? – Goofy Feb 16 '13 at 07:26
  • @Goofy you can directly kept it in a intent Extra..because LinkedHashmap is serializable...something like this intent.putExtra("hashmap",userlinkedhashmap); – Pragnani Feb 16 '13 at 10:50
  • @Pragnani I have tried your solution but I was getting ClassCastException as bundle always returns Hashmap object only, I am not getting how its working for you ? can you please update your answer with full code like how you are declaring Linked Hashmap and how you are passing and receiving it ? – Mac Feb 18 '13 at 08:54
  • @Mac I have updated the answer, It will return Hashmap and you need to cast it into LinkedHashMap – Pragnani Feb 18 '13 at 09:03
  • 2
    @Pragnani he is getting the error that hashmap cannot be cast to linkedhashmap. But you are again doing the same thing in your answer – Diffy Aug 15 '14 at 10:15
  • it didn't work for me this approach. I'm using [this solution](http://stackoverflow.com/questions/15922572/classcastexception-when-retrieving-data-from-bundle-on-android) – Juan Saravia May 18 '15 at 14:08
0

Pass as byte array, then deserialize and cast to a LinkedHashMap in target Activity.

Zizouz212
  • 4,908
  • 5
  • 42
  • 66
guest
  • 1
0

My approach is the following:

CustomObject must implement Parcelable. To set the bundle:

    LinkedHashMap<Integer, List<CustomObject>> mItems

    Bundle bundle = new Bundle();

    bundle.putInt("ItemsSize",mItems.size());          
    int mapIndex=0;

for(Map.Entry<Integer, List<CustomObject>> entry : mItems.entrySet()) {
    int key = entry.getKey();
    bundle.putInt("Key"+mapIndex, key);
    bundle.putParcelableArrayList("Value"+mapIndex, mItems.get(key));
    mapIndex++;
}

To get the bundle:

for(int i=0;i<bundle.getInt("ItemsSize");i++) {
    int key = bundle.getInt("Key"+i);
    ArrayList<CustomObject> value = bundle.getParcelableArrayList("Value"+i);
    mItems.put(key, value);
}
KaRa
  • 59
  • 7