Android异常篇 IllegalStateException: Can not perform this action after onSaveInstanceState

一、官方文档解析

public abstract int commit ()

Added in API level 11
Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.

A transaction can only be committed with this method prior to its containing activity saving its state. If the commit is attempted after that point, an exception will be thrown. This is because the state after the commit can be lost if the activity needs to be restored from its state. See commitAllowingStateLoss() for situations where it may be okay to lose the commit.

Returns
Returns the identifier of this transaction’s back stack entry, if addToBackStack(String) had been called. Otherwise, returns a negative number.

commit不是立即执行,而是当主线程在下一次准备好的时候进行修改,也就是说,这个函数只是把请求放到队列中去。

同时,commit操作必须在父容器saving state之前,因为当父容器saving state,意味着父容器可能会被销毁,这个时候这个commit可能会变成无效的。

二、解决方案 - commitAllowingStateLoss()

public abstract int commitAllowingStateLoss ()

Like commit() but allows the commit to be executed after an activity’s state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.

允许在XXXActivity执行onSaveInstanceState后进行Fragment修改

  public static void showInstance(XXXXActivity activity) {
        Bundle bundle = new Bundle();
        XXXDialog dialog = new XXXDialog ();
        dialog .setArguments(bundle);

	//  正确方式 :commitAllowingStateLoss()
        FragmentManager supportFragmentManager = activity.getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        fragmentTransaction.add(dialog ,"XXXTag");
        fragmentTransaction.commitAllowingStateLoss();

	 //   原有导致异常的方式:show() 本质上也是调用commit
     //   dialog.show(activity.getSupportFragmentManager(), "XXXTag");

    }

三、解决方案 - 反射

public class BDialogFragment extends DialogFragment {
 
    View rootView;
    Context mContext;
    
    // 可以不添加
    public View getRootView(ViewGroup container, int resId) {
        mContext = getActivity();
        rootView = LayoutInflater.from(mContext).inflate(resId, container, false);
        return rootView;
    }
 
    // 可以不添加
    public <T extends  View> T obtainView(int resId){
        if(null == rootView){
            return null;
        }
        return (T) rootView.findViewById(resId);
    }
 
    /**
     * 反射关键方法
     * @param manager
     * @param tag
     */
    @Override
    public void show(FragmentManager manager, String tag) {
        try{
            Field dismissed = DialogFragment.class.getDeclaredField("mDismissed");
            dismissed.setAccessible(true);
            dismissed.set(this,false);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
 
        try {
            Field showByMe = DialogFragment.class.getDeclaredField("mShownByMe");
            showByMe.setAccessible(true);
            showByMe.set(this,true);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
 
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

其子昱舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值