问题:
   
- 
     Activity重建后,为什么 ViewPager里的Fragment多了一倍
- 我的case:自己在ViewPager的adapter里 new的Fragment,系统又 restore 一个 Fragment。
 - 然后业务逻辑用 new的Fragment,系统却用restore的Fragment,导致new的Fragment声明周期都没走,之后就会各种异常。
 
 - 
     怎样复现 activity 被回收: 开发者选项,点击 不保存活动
- 这样Activity stack中不可见的(即不在stack 顶部的Activity都会被回收 (走onActivityDestroyed回调))
 
 - 
     什么时候,FragmentManager的内容被 restore: Activity的 super.onCreate(savedInstanceState); 执行完后恢复
- debug查看
 
 - 怎么创建Fragment (下文有写)
 
    
    
    结论先行
   
- 创建Fragment时,要考虑到Fragment被恢复的case,这时不该 new,而是 恢复状态
 - 
     Activity被 销毁 重建后,如果用ViewPager用的 FragmentStatePagerAdapter,系统会重新创建 Fragment 实例
- Activity被销毁时,FragmentManagetImpl 调用saveAllState,将保存Fragment的状态 FragmentManagerState(Parcelable子类 IPC跨进程使用)。
 - Activity重建时,会根据 FragmentManagerState ,重新创建Fragment
 
 - 
     编写Activity时,一定要考虑他会被destroy的情景(比如内存紧张, 这不受你控制)
- 一个内存泄漏就可以引发,当然泄漏多了就OOM,看起来指标不治本
 
 
Parcelable saveAllState() {
	                FragmentManagerState fms = new FragmentManagerState();
                fms.mActive = active;
                fms.mAdded = added;
                fms.mBackStack = backStack;
    
    
    怎么创建Fragment
   
创建时,一定要判断 FragmentMananger 中是否已有Fragment
    
    
    Fragment的创建、恢复(不用ViewPager)
   
private MainFragment mainFragment;
private SecondaryFragment secondaryFragment;
 
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        mainFragment = (MainFragment) fm.getFragment(savedInstanceState, MainFragment.TAG);
        secondaryFragment = (SecondaryFragment) fm.getFragment(savedInstanceState, SecondaryFragment.TAG);
    }
    if (mainFragment == null) {
        mainFragment = new MainFragment();
    }
    if(secondaryFragment == null){
        secondaryFragment = new SecondaryFragment()
    }
    // ViewPager 的相关操作
}
 
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (mainFragment.isAdded()) {
        fm.putFragment(outState, MainFragment.TAG, mainFragment);
    }
    if (secondaryFragment.isAdded()) {
        fm.putFragment(outState, SecondaryFragment.TAG, secondaryFragment);
    }
}
    
    
    Fragment + ViewPager
   
YourActivity
    private final YourFragmentAdapter adapter = new YourFragmentAdapter(getSupportFragmentManager());
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	adapter.initData();
    	viewPager.setAdapter(adapter);
    }
    //...........
YourAdapter
public class YourAdapter extends FragmentStatePagerAdapter {
    private final List<Fragment> tabFragments = new ArrayList<>();
    public YourAdapter(FragmentManager supportFragmentManager) {
        super(supportFragmentManager);
    }
    private void initData(FragmentManager fragmentManager) {
        YouFragment1 normalFragment = null;
        YouFragment2 specialFragment = null;
        if (fragmentManager != null && fragmentManager.getFragments().size() > 0) {
            List<Fragment> fragments =  fragmentManager.getFragments();
            for (int i = 0; i<fragments.size(); i++) {
                Fragment fragment = fragments.get(i);
                if (fragment instanceof YouFragment1) {
                    normalFragment = (YouFragment1) fragment;
                } else if (fragment instanceof YouFragment2) {
                    specialFragment = (YouFragment2) fragment;
                }
            }
        }
        if (normalFragment == null) {
            normalFragment = YouFragment1.newInstance();
        }
        if (specialFragment == null) {
            specialFragment = YouFragment2.newInstance();
        }
        tabFragments.add(normalFragment);
        tabFragments.add(specialFragment);
    }
    @Override
    public Fragment getItem(int position) {
        return tabFragments.get(position);
    }
    @Override
    public int getCount() {
        return tabFragments.size();
    }
    
    
    FragmentPagerAdapter 与 FragmentStatePagerAdapter
   
- 
     看这个
文章
 - 
     FragmentPagerAdapter 是将Fragment保存到 FragmentManager里,进行复用
- 适合静态的、少界面的ViewPager,加载Fragment过多,会增加内存消耗
 
 - 
     FragmentStatePagerAdapter 是通过对 FragmentManagerState 来实现状态的复用(Fragment会被新创建,但状态一致)
- 默认不保存所有的Fragment,而是 前页面1个+当前+后页面1个= 3个页面被缓存
 - 前面、后面页面缓存个数通过 ViewPager setOffscreenPageLimit (int limit)设置
 - 可以在Activity销毁重建后,回复UI状态
 
 
 
版权声明:本文为zhjali123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。