AsyncTask上的IllegalStateException [重复]

问题描述 投票:-1回答:1

在收到AsyncTask的响应时尝试替换片段时出现以下错误:

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

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

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

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

android android-asynctask illegalstateexception
1个回答
2
投票

您应该在java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState阅读WeakReference解决方案(或者也可能是其他解决方案)。


这个问题有一个替代解决方案。使用flag您可以处理它,如下所示

/**
 * 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值。

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()自26.1.0以来已添加,也可用于相同目的。

© www.soinside.com 2019 - 2024. All rights reserved.