What to do on TransactionTooLargeException

前端 未结 30 3389
盖世英雄少女心
盖世英雄少女心 2020-11-22 03:08

I got a TransactionTooLargeException. Not reproducible. In the docs it says

The Binder transaction failed because it was too large.

D

30条回答
  •  灰色年华
    2020-11-22 03:47

    The TransactionTooLargeException has been plaguing us for about 4 months now, and we've finally resolved the issue!

    What was happening was we are using a FragmentStatePagerAdapter in a ViewPager. The user would page through and create 100+ fragments (its a reading application).

    Although we manage the fragments properly in destroyItem(), in Androids implementation of FragmentStatePagerAdapter there is a bug, where it kept a reference to the following list:

    private ArrayList mSavedState = new ArrayList();
    

    And when the Android's FragmentStatePagerAdapter attempts to save the state, it will call the function

    @Override
    public Parcelable saveState() {
        Bundle state = null;
        if (mSavedState.size() > 0) {
            state = new Bundle();
            Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
            mSavedState.toArray(fss);
            state.putParcelableArray("states", fss);
        }
        for (int i=0; i

    As you can see, even if you properly manage the fragments in the FragmentStatePagerAdapter subclass, the base class will still store an Fragment.SavedState for every single fragment ever created. The TransactionTooLargeException would occur when that array was dumped to a parcelableArray and the OS wouldn't like it 100+ items.

    Therefore the fix for us was to override the saveState() method and not store anything for "states".

    @Override
    public Parcelable saveState() {
        Bundle bundle = (Bundle) super.saveState();
        bundle.putParcelableArray("states", null); // Never maintain any states from the base class, just null it out
        return bundle;
    }
    

提交回复
热议问题