Activity回收时候fragment的异常

本文探讨了Android中使用V4包内的Fragment时遇到的问题,即Activity被回收但Fragment仍保留状态,导致重新加载时出现问题。文章提供了具体的解决方案,包括在特定情况下清除Fragment的保存状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Android开发中,如果我们用到V4包里面的Fragment,在应用被切换到后台的时候,Activity可能被回收,但是创建的所有Fragment则会被保存到Bundle里面,下面是FragmentActivity的部分源码

    /*
     * Save all appropriate fragment state. 
     */ 
    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
          super.onSaveInstanceState(outState); 
           Parcelable p = mFragments.saveAllState(); 
          if (p != null) { 
              outState.putParcelable(FRAGMENTS_TAG, p); 
          } 
   }

如果从最近使用的应用里面点击我们的应用,系统会恢复之前被回收的Activity,这个时候FragmentActivity在oncreate里面也会做Fragment的恢复,

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mFragments.attachActivity(this, mContainer, null);
        // Old versions of the platform didn't do this!
        if (getLayoutInflater().getFactory() == null) {
            getLayoutInflater().setFactory(this);
        }

        super.onCreate(savedInstanceState);

        NonConfigurationInstances nc = (NonConfigurationInstances)
                getLastNonConfigurationInstance();
        if (nc != null) {
            mAllLoaderManagers = nc.loaders;
        }
        if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
        }
        mFragments.dispatchCreate();
    }

但是此时恢复出的Fragment,在调用getActivity的时候会返回null,具体什么原因还没详细研究,这里我的解决方法是在恢复Fragment之前把保存Bundle里面的数据给清除,也就是保存的Fragment信息,然后自己重新replace。方法如下:

if(arg0 != null)
        {
            String FRAGMENTS_TAG = "android:support:fragments";
            // remove掉保存的Fragment
            arg0.remove(FRAGMENTS_TAG);
        }

注:如果是FragmentActivity则在 onCreate之前添加如下

if (savedInstanceState != null) { 
         savedInstanceState.putParcelable(“android:support:fragments”, null); 
    } 
super.onCreate(savedInstanceState); 

如果是actvity
改成是“android:fragments”

如果系统内存不足、或者切换横竖屏、或者app长时间在后台运行,Activity都可能会被系统回收,然后Fragment并不会随着Activity的回收而被回收,从而导致Fragment丢失对应的Activity。

这里,假设我们继承于FragmentActivity的类为MainActivity,其中用到的Fragment为FragmentA。

app发生的变化为:某种原因系统回收MainActivity——FragmentA被保存状态未被回收——再次点击app进入——首先加载的是未被回收的FragmentA的页面——由于MainActivity被回收,系统会重启MainActivity,FragmentA也会被再次加载——页面出现混乱,因为一层未回收的FragmentA覆盖在其上面——(假如FragmentA使用到了getActivity()方法)会报空指针,出现crash。

原理虽然有点绕,但是解决办法很简单:

MainActivity重写onSaveInstanceState方法,将super.onSaveInstanceState(outState);注释掉,让其不再保存Fragment的状态,达到其随着MainActivity一起被回收的效果!

相关文章:
http://www.imooc.com/wenda/detail/237724
http://www.voidcn.com/article/p-vgvrzbai-wg.html
http://blog.youkuaiyun.com/w958796636/article/details/50617640

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值