示例代码:https://gitee.com/spectre1225/big-data-demo.git
问题场景
在Activity之间跳转时,可能因为传递大型数据导致抛出TransactionTooLargeException异常,或许是传递一个Bitmap,或许是一个长度非常长的List或数组,甚至可能是一个长得离谱的String。
碰到这类问题的时候,我们通常会采用:
- 通过某个全局可见的第三者(比如某个单例类)在内存中共享这个大型数据。
缺点:1. 类似全局变量,不安全;2. 无法用于闹钟或通知中的Bundle,因为触发时应用可能已经重启过了,内存信息被清理了。
- 写到数据库/文件中,读取的时候访问数据库/文件。
缺点:1. 操作和维护麻烦。
且上面方法有一个共同的问题:我需要一个参数,却得到了一个环境变量/全局上下文变量。
因此,我需要一种方案,可以:
- 避免
TransactionTooLargeException异常 - 在使用上和
Intent/Bundle兼容
实现思路
其实不管是写文件/数据库,还是通过内存变量来共享,都解决了TransactionTooLargeException异常,主要问题还是没法像其他数据那样通过Intent/Bundle来传递,达不到“参数”的效果。
那么我们可以封装一种数据结构,可以通过Intent/Bundle来传递和使用,但内部使用文件/数据库/全局变量就可以了。
MemoryBigData
首先是通过内存变量的方式,我们只要定义一个类,使之实现Serializable或Parcelable接口,用于序列化传输,然后数据放在内部定义的静态Map中,就像这样:
public class MemoryBigData<T> implements Serializable {
private static final ConcurrentHashMap<String, Object> CACHE_MAP = new ConcurrentHashMap<>();
//......
}
设置参数的代码,可以写成:
Intent intent = new Intent(this, TestActivity.class);
intent.putExtra("bigIntData", MemoryBigData.of(new int[1024 * 1024]));
startActivity(intent);
读取参数的时候,就是:
MemoryBigData<int[]> intsData = (MemoryBigData<int[]>) getIntent().getSerializableExtra("bigIntData");
int[] ints1 = intsData.get();//直接读取
Log.d("TestActivity", "onCreate => data:" + ints1);
//或
int[] ints2 = intsData.getAndRemove();//读取并删除,不删除可能会导致内存溢出
Log.d("TestActivity", "onCreate => remove: " + ints2 + " - " + intsData.isPresent());
MemoryBigData类的完整实现如下:
public class MemoryBigData<T> implements Serializable {
private static final ConcurrentHashMap<String, Object> CACHE_MAP = new ConcurrentHashMap<>();
public static <T> MemoryBigData<T> of(

本文介绍了如何在Android应用中处理Activity间由于大型数据导致的TransactionTooLargeException,提出MemoryBigData和FileBigData两种解决方案,前者利用内存共享,后者支持持久化存储,同时保持与Intent/Bundle的兼容性。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



