Activity间通过Intent传递数据的大小限制。

来源:互联网 发布:蒙自网络问政平台 编辑:程序博客网 时间:2024/06/06 01:41

这个问题没找到官方说明,针对网上的各种答案,自己实际测试了一下。

0x01结论

1.1传512K以下的数据的数据可以正常传递。

1.2传512K~1024K的数据会出错,闪退。

1.3传1024K以上的数据会报错:TransactionTooLargeException。

1.4考虑到Intent还包括要启动的Activity等信息,实际可以传的数据略小于512K

0x02准备工作

2.1怎么查看占用内存大小

见参考文献1、2。

2.2构建要传的数据

①我们构建一个1K的字符串;
②再构建ArrayList的字符串列表;
③用Intent.putStringArrayListExtra传递
我们知道1个char占2个字节,那么构建一个512的字符串就刚好1K了。
实测的时候发现512占了1040,于是减掉8个,取504个。

        int size=504;        mStringBuilder=new StringBuilder(size);        for(int i=0;i<size;i++){            mStringBuilder.append("a");        }        //这个mString占1024bytes        mString=mStringBuilder.toString();

2.3循环测试

public void openActivity() {        try {            mIntent = new Intent(this, TestActivity2.class);            //这里要注意的,只有每次都add一个新的字符串,mStringList的大小才会线性变大,否则,指向的是同一个地址            //但是,即使指向同一个地址,在put的时候也是会出错的,原因,就是因为put要放入每一个值吧。            mStrngList.add(mStringBuilder.toString());            mIntent.putStringArrayListExtra("string_list", mStrngList);            Log.d("test", "put size:" + mStrngList.size());            startActivityForResult(mIntent, REQUEST_CODE_TEST);        }catch (Exception e){            e.printStackTrace();        }    }    //在这里在调用打开,就循环了    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(resultCode==RESULT_OK && requestCode==REQUEST_CODE_TEST && mContinue){            openActivity();        }    }

2.4分析第509的时候闪退

当mArrayList的size是509的时候,就闪退了。
有以下两张图。
508
509
可以看到508的时候
522936/1024=510.68
509的时候
523960/1024=511.68
虽然还没有到512,但我还是得出512的结论,原因是Intent的其他内容也要占内存,所以诱发闪退的原因应该是512.

2.5循环查找TransactionTooLargeException下限

改下测试代码

public void openActivity() {        try {            mIntent = new Intent(this, TestActivity2.class);            mStrngList.remove(0);            Log.d("test", "try put size:" + mStrngList.size());            mIntent.putStringArrayListExtra("string_list", mStrngList);            startActivityForResult(mIntent, REQUEST_CODE_TEST);            Log.d("test", "put success:" + mStrngList.size());        }catch (Exception e){            e.printStackTrace();            openActivity();        }    }

2.6分析1018下限

1018的时候闪退,1019时捕获异常。

E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 1039780)Caused by: android.os.TransactionTooLargeException: data parcel size 1039780 bytes

这个官方是有说明的,最在1M(见参考文献3),
上面的1039780/1024=1015.41,哈哈,不要在乎这些细节。
看下面2张图
1018
1019
1046536/1024=1022.01
1047560/1024=1023.01

0x03参考文献

[1]基于Android Studio的内存泄漏检测与解决全攻略
[2]使用新版Android Studio检测内存泄露和性能
[3]TransactionTooLargeException
[3]江湖问题研究– intent传递有没有大小限制,是多少?

0 0