HashMap of WeakReferences for passing data between

2020-07-27 03:39发布

问题:

I am particulary interested in the following suggestion from the official android FAQ.

A HashMap of WeakReferences to Objects

You can also use a HashMap of WeakReferences to Objects with Long keys. When an activity wants to pass an object to another activity, it simply puts the object in the map and sends the key (which is a unique Long based on a counter or time stamp) to the recipient activity via intent extras. The recipient activity retrieves the object using this key.`

I haven't found a way how to properly implement this. And I'm not sure why WeakReferences are preferred here and why not use hard references.

My implementation (I would like to send an instance of class XY from the activity A to the service B):

  • the receiving service has a static HashMap of Objects.

    public static HashMap<Long, Object> parameters = new HashMap<Long, Object>();
    
  • code for the sending part (activity A)

    long key = SystemClock.elapsedRealtime();
    B.parameters.put(key, new XY());
    Intent i = new Intent(this, B.class);
    i.putExtra("PARAM_UPLOAD", key);
    startService(i);
    
  • code for the receiving part (service B)

    long key = intent.getLongExtra("PARAM_UPLOAD", -1);
    XY data = (XY)parameters.get(key);
    

The code is using hard references. Why should I use weak references here (as proposed by the FAQ)? And is such a use pattern for passing data ok or do you prefer something else.

回答1:

Why should I use weak references here (as proposed by the FAQ)?

Because you are leaking memory. Anything you put in that static HashMap is never garbage-collected.

And is such a use pattern for passing data ok or do you prefer something else.

I prefer only passing simple data between activities. Anything that isn't a primitive (or a system-supplied Parcelable, like a PendingIntent) should be considered part of the data model and should be managed as such. Here is a blog post where I go into more details.