1. 程式人生 > >Activity間通過Intent傳遞資料的大小限制。

Activity間通過Intent傳遞資料的大小限制。

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 
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張圖 
1018 
1019 
1046536/1024=1022.01 
1047560/1024=1023.01

0x03參考文獻