Activity間通過Intent傳遞資料的大小限制。
阿新 • • 發佈:2019-02-10
http://blog.csdn.net/pingfangx/article/details/52093225
這個問題沒找到官方說明,針對網上的各種答案,自己實際測試了一下。
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();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
2.4分析第509的時候閃退
當mArrayList的size是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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2.6分析1018下限
1018的時候閃退,1019時捕獲異常。
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 1039780)
Caused by: android.os.TransactionTooLargeException: data parcel size 1039780 bytes
- 1
- 2
- 3
- 1
- 2
- 3
這個官方是有說明的,最在1M(見參考文獻3),
上面的1039780/1024=1015.41,哈哈,不要在乎這些細節。
看下面2張圖
1046536/1024=1022.01
1047560/1024=1023.01