0

I have a LinkedHashMap that I want to pass through the Bundle savedInstanceBundle to store it between screen rotations. How do I do this safely? Before I just cast it because I know what I'm putting into it and what I'm getting out of it, but this did generate a warning that it was considered an unsafe cast.

What I am doing now :

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        if(thumbnails != null) {
            savedInstanceState.putSerializable("thumbnails", thumbnails);
        }
    }

and retrieving it

thumbnails = (LinkedHashMap<Long, Bitmap>)savedInstanceState.getSerializable("thumbnails");

What is the correct way to deserialize LinkedHashMaps from a Bundle? Can it be done at all? If not, how do I preserve order without adding another layer in between that keeps track of the position which would involve changing a lot of existing code?

` Caused by: java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap`
G_V
  • 2,396
  • 29
  • 44
  • is thumbnails an HashMap or a LinkedHashMap? – Blackbelt Dec 11 '14 at 13:52
  • It is a LinkedHashMap – G_V Dec 11 '14 at 14:06
  • You cannot reliably insert/retrieve a `LinkedHashMap` to/from a `Bundle` in Android. What you get back is a `HashMap`, not a `LinkedHashMap`. See [my answer to this question](http://stackoverflow.com/a/38960732/769265) for more details – David Wasser Aug 15 '16 at 18:36

1 Answers1

2

From the MVC (Model -- View -- Controller) point of view, an Activity is a Controller. (And so is a Fragment.) The View is made from the XML and the Android View subclasses that you reuse (people rarely define custom View subclasses). And the Model is --- well, you have to define a class for the Model yourself! If you had Model, you'd look from a different perspective.

But if you nevertheless want to pass data from one Activity incarnation to another -- well, why don't you use a JSONObject/JSONArray? It's an overkill, it will be slow, but it should at least work.

Another possibility is to convert the LinkedHashMap into a list of key-value pairs and later reconstruct it from that list.

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127
  • Very interesting suggestions. I already have a Gson facade class implemented so conversion back and forth shouldn't be a problem. After 15 pages of google results I now understand this is due to java generics converting it to a HashMap first, so there's no way to maintain order with a standard LinkedHashMap anyway. If that doesn't work well with images, I'll expand the wrapper class I currently have and use it to recreate the LinkedHashMap. All seems a bit expensive but at least it'll work. I'm inspired, thanks! – G_V Dec 11 '14 at 15:06
  • Well, both solutions worked but were really slow so I ended up changing my code and using an ArrayList for better performance. – G_V Dec 11 '14 at 16:05
  • Please note that the _Model_ is what must survive a screen turn. The _Model_ dies only when the process is killed, so it must be saved in _onPause()_, but you don't have to pack/unpack it when the screen display changes. When the _Model_ dies, the static pointers get set to null (well, to their default values), so you can detect that. – 18446744073709551615 Dec 12 '14 at 09:19
  • I'm using a viewpager which calls camera functionality on every page, as far as I know onPause() is never called. – G_V Dec 12 '14 at 09:27
  • AFAIK that's not possible. How did you check? I can believe that a breakpoint does not work, but `Lod.d("~~~","~~~onPause()")` should show in `adb logcat | grep '~~~'`. – 18446744073709551615 Dec 12 '14 at 09:51
  • http://stackoverflow.com/questions/10853611/viewpager-with-fragments-onpause-onresume – G_V Dec 12 '14 at 10:02
  • As I understand, the process cannot be killed when the pager goes from one fragment to another, so the model cannot die, so there's no need to save it. The singleton will live. It is when the Activity goes away that _onPause()_ is called, and you have to save the _Model_ because the process may be killed due to e.g. lack of memory. – 18446744073709551615 Dec 12 '14 at 12:14