The way the Activity passes data

In general, when we jump from Activity A to Activity B, we use an Intent or A bundle to transfer data. Here’s an example:

Intent Intent = new Intent(Activity A.this, Activity B.class);

intent.putExtra(“abc”, “I am a String”);

intent.putExtra(“list”, dataList);

If the dataList data above is too large, such as more than 1M, then crash will occur and Activity B’s onCreate will not be executed. One of the problems I encountered in the project was that WHEN I checked the large picture of a certain picture in the album, I needed to pass all the paths of all the pictures. However, when there were thousands of pictures and the data exceeded 1M, there was an abnormal startup crash.

The official document has mentioned that the anomaly is TransactionTooLargeException, transfer data or abnormal data is too large. And the sentence “Parcel objects stored in the Binder transaction buffer” is mentioned, This indicates that the underlying parcel object actually holds a place called the Binder Transaction Buffer between activities, which must have a size limit.

The solution

Since the data passed is limited in size, we cannot use intEnts to transfer data.

So we define a static class DataHolder, and set setData and getData methods, and considering the extreme case, it is possible to pass the object memory is extremely large, so in order not to cause memory leakage, we will pass the object constructed as a weak reference to the static class. Here is the code for DataHolder:

public class DataHolder {

    private Map dataList = new HashMap<>();

    private static volatile DataHolder instance;

    public static DataHolder getInstance() {

       if(instance==null) {

            synchronized(DataHolder.class) {

                if(instance==null) {

                     instance = new DataHolder();

                }

           }

       }

       return instance;

    }

    public void setData(String key, Object o) {

        WeakReference value =new WeakReference<>(o);

        dataList.put(key, value);

    }

    public Object getData(String key) {

          WeakReference reference =dataList.get(key);

if(reference ! =null) {

              Object o = reference.get();

              return o;

          }

          return null;

      }

}

In the future, when we want to transmit big data, we can use dataholder.setData (name, value) for transmission, and then use dataHolder.getData (name) for acquisition in the target Activity.