在AsyncTask上的IllegalStateException [英] IllegalStateException on AsyncTask

查看:114
本文介绍了在AsyncTask上的IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从AsyncTask收到响应后,尝试替换片段时出现以下错误:

I'm getting a following error when trying to replace a fragment upon receiving a response from AsyncTask:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

问题是,通过Android Studio重新启动我的应用程序后,我随机收到此错误.在简化版本中,我的活动包含4个关键方法(onCreate,taskCompleted,parseJSON和fragmentReplace),这些方法确定用户应在开始时看到哪个片段:

The thing is, I get this error randomly upon restarting my app through Android Studio. In a simplified version my activity contains 4 key methods (onCreate, taskCompleted, parseJSON and fragmentReplace), that determine which fragment should the user see at the start:

private AsyncTask mMyTask;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mMyTask = new AsyncTask(this, this);
    mMyTask.executeTaskCall("check_user");
}


@Override
public void taskCompleted(String results) {
    try {
        JSONObject jsonBody = new JSONObject(results);
        parseJSON(jsonBody);
    }
    catch (JSONException je){
    }
}

private void parseJSON(JSONObject jsonBody) throws JSONException {
    boolean userActive = jsonBody.getBoolean("result");

    if (userActive){
        fragmentReplace(new FirstFragment(), "FirstFragment");
    }
    else {
        fragmentReplace(new SecondFragment(), "SecondFragment");
    }
}

public void fragmentReplace(Fragment fragment, String fragmentTag){
    getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.layout_container, fragment, fragmentTag)
            .commit();
}

此异常如此随机发生的原因是什么?

What is the reason of this exception happening so random?

推荐答案

您应该在对于此问题,有一种替代解决方案.使用标志可以处理它,如下所示

There is one alternate solution for this problem. Using flag you can handle it, like below

/**
 * Flag to avoid "java.lang.IllegalStateException: Can not perform this action after
 * onSaveInstanceState". Avoid Fragment transaction until onRestoreInstanceState or onResume
 * gets called.
 */
private boolean isOnSaveInstanceStateCalled = false;


@Override
public void onRestoreInstanceState(final Bundle bundle) {
    .....
    isOnSaveInstanceStateCalled = false;
    .....
}

@Override
public void onSaveInstanceState(final Bundle outState) {
    .....
    isOnSaveInstanceStateCalled = true;
    .....
}

@Override
public void onResume() {
    super.onResume();
    isOnSaveInstanceStateCalled = false;
    .....
}

您可以在执行片段交易时检查此 boolean 值.

And you can check this boolean value while doing fragment transaction.

private void fragmentReplace(Fragment fragment, String fragmentTag){
    if (!isOnSaveInstanceStateCalled) {
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.layout_container, fragment, fragmentTag)
                .commit();
    }
}


API 26.1+的更新(由 Stephen M 提供)

Fragment.isStateSaved(),也可以用于相同的目的.

Fragment.isStateSaved() has been added since 26.1.0, which can also be used for same purpose.

这篇关于在AsyncTask上的IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆