处理fragment获取getActivity为null的问题

问题:
应用从后台进入前台时,fragmeng中getActivity()获取null ,导致崩溃问题
原因:
当系统资源紧张时,或者被gc回收activity,但是进程还保留时,Activity都可能会被系统回收然后重建,在系统要把App回收之前,系统会把Activity的状态会保存下来,但Fragment并不会随着Activity的回收而被回收,创建的所有Fragment会被保存到Bundle里面,从而导致Fragment丢失对应的Activity。

void restoreChildFragmentState(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(
                    FragmentActivity.FRAGMENTS_TAG);
            if (p != null) {
                if (mChildFragmentManager == null) {
                    instantiateChildFragmentManager();
                }
                mChildFragmentManager.restoreAllState(p, mChildNonConfig);
                mChildNonConfig = null;
                mChildFragmentManager.dispatchCreate();
            }
        }
    }

第一种解决方法
在basefragment中处理onAttach,从生命周期上保证

@RequiresApi(23)
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext = context;
        L.d("BaseFragment","Context的mContext是否为null"+(mContext==null));
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
          mContext = activity;
            L.d("BaseFragment","Activity的mContext是否为null"+(mContext==null));
        }
    }
 @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getActivity();
    }

    /**
     * 确保获取 不为null的上下文
     * @return
     */
    protected Context getBaseContext(){
        if(mContext != null){
            return mContext;
        }else {
            if(context != null){
                return context;
            }else {
            //到这里,已经基本不能为null,getActivity()最好换成application的context
                return getActivity();
            }
        }
    }

第二种方法
不保存fragment的状态:在homeactivity中重写onSaveInstanceState方法,将super.onSaveInstanceState(outState);注释掉,让其不再保存Fragment的状态,达到fragment随homeactivity一起销毁的目的。

 @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt("menuID", currentPage.menuID);
        super.onSaveInstanceState(outState);
    }

代码中有用到onSaveInstanceState ,该方法不适用。而且一般情况要处理savedInstanceState

第三种方法
重建时清除已经保存的fragment的状态:在恢复Fragment之前把Bundle里面的fragment状态数据给清除。

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
     outState.putInt("menuID", currentPage.menuID);
    if(outState!=null){
        outState.remove("android:support:fragments");
    }
}

代码中有用到onSaveInstanceState ,该方法不适用。

目前第一种方法比较适用。或者重新处理homeactivity的onCreate(Bundle savedInstanceState) 中的savedInstanceState。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值