5

So i want to pass a LinkedHashMap to an intent.

//SEND THE MAP
Intent singlechannel = new Intent(getBaseContext(),singlechannel.class);
singlechannel.putExtra("db",shows1);//perase to
startActivity(singlechannel);

//GET THE MAP
LinkedHashMap<String,String> db = new LinkedHashMap<String,String>();   
db=(LinkedHashMap<String,String>) getIntent().getSerializableExtra("db");

This one Worked Like a charm with HashMap. But with LinkedHashMap i got a problem i got a runtime error here

  db=(LinkedHashMap<String,String>) getIntent().getSerializableExtra("db");

I get no error with HashMap.

I also got a warning "Type safety: Unchecked cast from Serializable to LinkedHashMap" But i had this warning with HashMap too. Any ideas.Any help is much appreciated

Also I just saw this. https://issues.apache.org/jira/browse/HARMONY-6498

weakwire
  • 9,284
  • 8
  • 53
  • 78

2 Answers2

4

The root of the problem here is that you are trying to type cast to a generic type. This cannot be done without an unsafe/unchecked type cast.

The runtime types of generic types are raw types; i.e. types in which the actual types of the type parameters are not known. In this case the runtime type will be LinkedHashMap<?, ?>. This cannot be safely typecast to LinkedMashMap<String, String> because the runtime system has no way of knowing that all of the keys and values are actually String instances.

You have two options:

  • You could add an annotation to tell the compiler to "shut up" about the unchecked cast. This is a bit risky. If for some reason one of the keys or values is not actually a String, your application may later get a ClassCastException at a totally unexpected place; e.g. while iterating the keys or assigning the result of a get.

  • You could manually copy the deserialised Map<?, ?> into a new LinkedMashMap<String, String>, explicitly casting each key and value to String.

UPDATE

Apparently the real cause of the runtime exception (as distinct from the "unsafe typecast" compilation error) is that Android is passing the serializedExtra between intents as a regular HashMap rather than using the Map class that you provided. This is described here:

As that Q&A explains, there is no simple workaround. If you want to pass a map preserving the key order, will have to convert the map to an array of pairs and pass that. On the other end, you will then need to reconstruct the map from the passed array.

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • well about the annotation it tells the compile to shut up but doesn't solve the problem.I get a warning not an error.The error i get is on runtime and can't really understand why.It's a class exception in utils.LinkedHashMap.java 2nd answer not solving the problem again. The problem is that LinkedHashMap cannot be serialized for some reason But ofc ty very much for your answer and the time you took to write it – weakwire May 23 '10 at 02:35
  • 1
    Your question is about a compiler warning and my answer tells you 2 ways to deal with that compiler warning. If you are ALSO getting runtime errors, you should have said so in the question ... and you should also provide the stack trace. Unlike Jon Skeet, I cannot read your mind. – Stephen C May 23 '10 at 02:43
  • I am very sorry.You are right i'm looking this for too long now.Sorry again i just edited my first post – weakwire May 23 '10 at 02:51
  • Actually, the root of the problem here is that the call to ` getIntent().getSerializableExtra("db")` returns a `HashMap` and not a `LinkedHashMap`. This has nothing to do with Harmony, it is an Android idiosyncrasy. – David Wasser Aug 15 '16 at 18:33
2

LinkedHashMap does implement Map interface, here is definition from the source code:

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>

The following test is working fine, so I think the problem you have is not related LinkedHashMap.

Map<String, String> map = new LinkedHashMap<String, String>();
        map.put("1", "one");
        FileOutputStream fos = new FileOutputStream("c://map.ser");
        ObjectOutputStream out = new ObjectOutputStream(fos);
        out.writeObject(map);
        out.close();


        FileInputStream fin = new FileInputStream("c://map.ser");
        ObjectInputStream in = new ObjectInputStream(fin);
        Map<String, String> map2 = (Map<String, String>) in.readObject();
        System.out.println(map2); 
miz
  • 41
  • 2