应用在后台崩溃,从堆栈中弹出一个片段时。

3
当我点击服务器RPC时,应用程序崩溃,并且当RPC正在进行时,我将应用程序置于后台。同时,当RPC从服务器接收到响应时,它会从堆栈中弹出一个片段。在弹出片段的同时,应用程序崩溃了。 我已经阅读了关于创建 WeakReference 的文章,如果活动被销毁,它将为null。但不确定如何在这种情况下实现它。
以下是我的代码:
private void showFragment(SherlockFragment fragment) {
    FragmentManager fm = getSupportFragmentManager();
    fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.content, fragment);
    ft.commit();
}

执行以下代码时出现崩溃:

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

堆栈跟踪:

01-15 16:37:44.435: E/AndroidRuntime(28049): FATAL EXCEPTION: main
01-15 16:37:44.435: E/AndroidRuntime(28049): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
01-15 16:37:44.435: E/AndroidRuntime(28049):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
01-15 16:37:44.435: E/AndroidRuntime(28049):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
01-15 16:37:44.435: E/AndroidRuntime(28049):    at android.support.v4.app.FragmentManagerImpl.popBackStack(FragmentManager.java:452)
01-15 16:37:44.435: E/AndroidRuntime(28049):    at com.druva.inSync.ValidationActivity$2.run(ValidationActivity.java:93)

1
搜索“在 onSaveInstanceState 后无法执行此操作”,你会得到很多很多的答案。 - Shayan Pourvatan
请提供需要翻译的英文内容。 - Mario Lenci
我查看了相关问题。我尝试使用"commitAllowingStateLoss",还尝试检查"activity.isFinishing"。控制权并没有到达'isFinishing',由于在ft.commit()之前出现崩溃,因此 commitAllowingStateLoss 也无济于事。 - Mayur More
1个回答

2

我曾经遇到过完全相同的问题,我用一个标志解决了它。这可能看起来有点“投机取巧”,但它确实可以解决问题。

public abstract class PopActivity extends Activity {

    private boolean mVisible; 

   @Override
    public void onResume() {
        super.onResume();
        mVisible = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        mVisible = false;
    }

    private void popFragment() {
        if (!mVisible) {
            return;
        }

        FragmentManager fm = getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }
}

因此,当您仅实现上述代码时,当您恢复应用程序时,您会发现自己处于一个实际上需要弹出的片段中。您可以使用以下代码片段来解决这个问题:

public abstract class PopFragment extends Fragment {

    private static final String KEY_IS_POPPED = "KEY_IS_POPPED";
    private boolean mPopped;

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putBoolean(KEY_IS_POPPED, mPopped);
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            mPopped = savedInstanceState.getBoolean(KEY_IS_POPPED);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mPopped) {
            popFragment();
        }
    }

    protected void popFragment() {
        mPopped = true;
        // null check and interface check advised
        ((PopActivity) getActivity()).popFragment();
    }
}

1
当片段回到前台时,由于onCreate方法未被调用,因此存在问题。 - JJ Ab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接