【问题标题】:Background tasks fragments and "Can not perfom this action after onSaveInstanceState"后台任务片段和“onSaveInstanceState 后无法执行此操作”
【发布时间】:2012-09-09 20:56:55
【问题描述】:

我在 Fragment 中有以下 AsyncTask(为了清楚地显示错误而简化了示例):

private class LoginTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {

        // Do network login
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        FragmentActivity act = (FragmentActivity) getActivity();
        if (act != null && isAdded()) {
            act.getSupportFragmentManager().beginTransaction()
                    .add(new LoginDialogFragment(), "loginMessage").commit();
        }
    }

}

有一次,在任务运行时离开应用,我收到了IllegalStateException: Can not perform this action after onSaveInstanceState

我想这是因为我在活动的 onSaveInstanceState 和从活动中取消附加片段之间调用了它(或者因为在 getActivity() 调用和添加片段调用之后活动没有附加。

那么我以后怎样才能避免这个错误呢?谢谢!

【问题讨论】:

    标签: java android multithreading android-fragments


    【解决方案1】:

    isFinishing() 方法应该可以帮到你。

    @Override
        protected void onPostExecute(Void result) {
            FragmentActivity act = (FragmentActivity) getActivity();
            if (act != null && !act.isFinishing() && isAdded()) {
                act.getSupportFragmentManager().beginTransaction()
                        .add(new LoginDialogFragment(), "loginMessage").commit();
            }
        }
    

    【讨论】:

    • isFinishing() 在应用程序完全退出后再次设置为false。仅在onPause() 之前到onDestroy() 结束时为真。
    • 谢谢一百万...我能以某种方式多次标记此答案有用吗..? ;)))
    【解决方案2】:

    onPauseonStoponDestroy 中,在AsyncTask 上调用.cancel()(这可能要求您的AsyncTask 是您活动中的成员变量)。然后,在您的 onPostExecute() 方法中,检查进程是否已取消。

    protected void onPostExecute(Void result) {
        if (!isCancelled()) { // Do stuff only if not cancelled
            FragmentActivity act = (FragmentActivity) getActivity();
            if (act != null && isAdded()) {
                act.getSupportFragmentManager().beginTransaction()
                        .add(new LoginDialogFragment(), "loginMessage").commit();
            }
        }
        return null;
    }
    

    注意:您可能还想在doInBackground() 中的任何循环中检查isCancelled(),这样您就不会在此人离开应用程序后继续做任何事情。

    【讨论】:

    • 感谢您的回答。由于我不想取消任务但只是不想崩溃,我将使用 act != null && isAdded() && isResumed()
    • 如果任务被取消,onPostExecute() 真的会被调用吗?这里的“取消任务”部分表明它不会,而是会调用 onCancelled:developer.android.com/reference/android/os/AsyncTask.html
    猜你喜欢
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2014-03-05
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    相关资源
    最近更新 更多