简体   繁体   English

当从堆栈弹出片段时,应用程序在后台崩溃

[英]Application crashes in background, when popping a fragment from stack

Application crashes, when I hit a server RPC, and when the RPC is in progress, I put the application in background. 应用程序崩溃,当我点击服务器RPC时,当RPC正在进行时,我将应用程序放在后台。 Meanwhile, when the RPC gets the response from server, it pops a fragment from stack. 同时,当RPC从服务器获取响应时,它会从堆栈中弹出一个片段。 While popping the fragment, the application crashes. 弹出片段时,应用程序崩溃。 I have read about creating WeakReference , which will be null if the activity is destroyed. 我已经阅读了有关创建WeakReference的内容 ,如果活动被销毁,它将为null。 But not sure how to implement it this case. 但不确定如何实现这种情况。

Following is my code : 以下是我的代码:

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();
}

I get a crash on executing the following line: 执行以下行时出现崩溃:

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

StackTrace : 堆栈跟踪 :

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)

I had the exact same problem, which I resolved using a flag. 我遇到了完全相同的问题,我使用旗帜解决了这个问题。 It may seem a little "hacky", but it does the job 它可能看起来有点“hacky”,但它确实起了作用

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);
    }
}

So when you implement the above code alone when you resume the app you will find yourself in a fragment that you actually want to be popped. 因此,当您在恢复应用程序时单独实现上述代码时,您会发现自己处于一个实际上想要弹出的片段中。 You can use the following snipped to fix this issue: 您可以使用以下剪辑来解决此问题:

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM