Android 使用FragmentStatePagerAdapter并启动新活动时TransactionTooLargeException

Android 使用FragmentStatePagerAdapter并启动新活动时TransactionTooLargeException,android,android-fragments,android-activity,fragmentstatepageradapter,Android,Android Fragments,Android Activity,Fragmentstatepageradapter,这实际上是一个源于其他地方的问题,但我已将其缩小到以下场景。在我的MainActivity中,我使用一个ViewPager在底部有三个选项卡来交换我的三个片段。如果在移动到任何片段后单击按钮移动到新活动,则会出现以下错误: FATAL EXCEPTION: main java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 861520 bytes at android.app.

这实际上是一个源于其他地方的问题,但我已将其缩小到以下场景。在我的MainActivity中,我使用一个ViewPager在底部有三个选项卡来交换我的三个片段。如果在移动到任何片段后单击按钮移动到新活动,则会出现以下错误:

FATAL EXCEPTION: main
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 861520 bytes
  at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3752)
  at android.os.Handler.handleCallback(Handler.java:751)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at android.app.ActivityThread.main(ActivityThread.java:6077)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.os.TransactionTooLargeException: data parcel size 861520 bytes
  at android.os.BinderProxy.transactNative(Native Method)
  at android.os.BinderProxy.transact(Binder.java:615)
  at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3606)
  at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3744)
  at android.os.Handler.handleCallback(Handler.java:751) 
  at android.os.Handler.dispatchMessage(Handler.java:95) 
  at android.os.Looper.loop(Looper.java:154) 
  at android.app.ActivityThread.main(ActivityThread.java:6077) 
  at java.lang.reflect.Method.invoke(Native Method) 
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
但是,如果在ViewPager中的不同片段之间移动之前单击该按钮,则不会发生崩溃。我已经探索了将我的片段完全清空的所有可能性,以查看问题是否存在,但它似乎与MainActivity或FragmentStatePageRadaper有关

以下是它们的代码:

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.mypackage.Fragments.GroupsFragment;
import com.mypackage.Fragments.HomeFragment;
import com.mypackage.Fragments.ProfileFragment;
import com.mypackage.R;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get the ViewPager and set it's PagerAdapter so that it can display items
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(new MainFragmentPagerAdapter(getSupportFragmentManager()));

        // Give the TabLayout the ViewPager
        TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
        tabLayout.setupWithViewPager(viewPager);

        Button mTestButton = (Button) findViewById(R.id.test);

        mTestButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                moveToGroupActivity();
            }
        });
    }

    public void moveToGroupActivity() {
        Intent myIntent = new Intent(this, GroupActivity.class);
        startActivity(myIntent);
    }

    public static class MainFragmentPagerAdapter extends FragmentStatePagerAdapter {

        final int PAGE_COUNT = 3;
        private String tabTitles[] = new String[] { "Home", "Groups", "Profile" };

        public MainFragmentPagerAdapter(FragmentManager fm) {
            super(fm);


 }

    @Override
    public int getCount() {
        return PAGE_COUNT;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return HomeFragment.newInstance();
            case 1:
                return GroupsFragment.newInstance();
            case 2:
                return ProfileFragment.newInstance();
            default:
                return null;
        }
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // Generate title based on item position
        return tabTitles[position];
    }
}

}
需要明确的是:我有一个按钮,可以在一个活动中移动到另一个活动,该活动由一个在三个片段之间移动的ViewPager组成。如果我在移动到另一个片段之前单击按钮,它将很好地加载。如果我移动到一个片段,然后点击按钮,我得到上面提到的崩溃


我从不使用onSaveInstanceState()或类似的东西。我唯一的猜测是FragmentStatePagerAdapter正在将碎片放入内存并导致崩溃,但我真的不知道。

TransactionTooLargeException已经困扰我们大约4个月了,我们终于解决了这个问题

所发生的事情是我们在ViewPager中使用了FragmentStatePagerAdapter。用户将翻阅并创建100多个片段(这是一个阅读应用程序)

尽管我们在destroyItem()中正确地管理了片段,但在FragmentStatePagerAdapter的Androids实现中有一个bug,它保留了对以下列表的引用:

private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();

此问题可以通过清除最后保存的对象实例来解决。尝试在活动课上使用

 @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.clear();
    }

当您在片段或活动之间传递大量数据时,会出现此问题。复制自此答案:
@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;
}
 @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.clear();
    }