Android 使用FragmentStatePagerAdapter并启动新活动时TransactionTooLargeException
这实际上是一个源于其他地方的问题,但我已将其缩小到以下场景。在我的MainActivity中,我使用一个ViewPager在底部有三个选项卡来交换我的三个片段。如果在移动到任何片段后单击按钮移动到新活动,则会出现以下错误: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.
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();
}