Andorid小技巧:TransactionTooLargeException的简洁处理

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

示例代码:https://gitee.com/spectre1225/big-data-demo.git

问题场景

在Activity之间跳转时,可能因为传递大型数据导致抛出TransactionTooLargeException异常,或许是传递一个Bitmap,或许是一个长度非常长的List或数组,甚至可能是一个长得离谱的String

碰到这类问题的时候,我们通常会采用:

  • 通过某个全局可见的第三者(比如某个单例类)在内存中共享这个大型数据。

缺点:1. 类似全局变量,不安全;2. 无法用于闹钟或通知中的Bundle,因为触发时应用可能已经重启过了,内存信息被清理了。

  • 写到数据库/文件中,读取的时候访问数据库/文件。

缺点:1. 操作和维护麻烦。

且上面方法有一个共同的问题:我需要一个参数,却得到了一个环境变量/全局上下文变量。

因此,我需要一种方案,可以:

  1. 避免TransactionTooLargeException异常
  2. 在使用上和Intent/Bundle兼容

实现思路

其实不管是写文件/数据库,还是通过内存变量来共享,都解决了TransactionTooLargeException异常,主要问题还是没法像其他数据那样通过Intent/Bundle来传递,达不到“参数”的效果。

那么我们可以封装一种数据结构,可以通过Intent/Bundle来传递和使用,但内部使用文件/数据库/全局变量就可以了。

MemoryBigData

首先是通过内存变量的方式,我们只要定义一个类,使之实现SerializableParcelable接口,用于序列化传输,然后数据放在内部定义的静态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(
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值