【问题标题】:AsyncTask while screen locked or overlapped by other app屏幕锁定或被其他应用程序重叠时的 AsyncTask
【发布时间】:2014-02-19 12:26:37
【问题描述】:

有一个带有“提交”操作的片段页面。 提交按钮将启动 AsyncTask.execute,在 doInBackground 中创建一些网络作业,然后将显示成功 Toast 消息并在 onPostExecute 中删除自身。

在 onPostExecute 发生时屏幕已经关闭的情况下,如何避免“IllegalStateException: Can't perform this action after onSaveInstanceState”?

是否可以等待popBackStack()或onBackPressed()等操作在锁定活动状态下无法完成?

PS 当前问题与屏幕旋转或其他配置更改事件无关。

代码示例(片段中的 AsyncTask):

private final class SubmitTask extends AsyncTask<Void, Void, String> {
        @Override
        protected String doInBackground(Void... voids) {
        //...
        }

        @Override
        protected void onPostExecute(String err) {
            if (err != null) {
                Toast.makeText(parentActivity, "Error occured: " + err, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(parentActivity, "Saved", Toast.LENGTH_SHORT).show();
                parentActivity.getSupportFragmentManager().popBackStack();// <<---- Exception crashed here
            }
        }

【问题讨论】:

  • 在您的 Toast 命令中,不要使用当前上下文,而是使用 getApplicationContext() 并查看这是否可以防止异常
  • 不,不是 - 问题可能不在于 toast,而在于调用 onSaveInstanceState() 后的一些 UI 交互,因此活动处于非法状态以执行此类操作。跨度>
  • IllegalStateException是由fragmentManager.popBackStack()引起的,用于关闭当前fragment并返回上一个。

标签: android android-fragments android-asynctask


【解决方案1】:

最简单的就是

try{....}

catch(IllegalStateException e){

}

【讨论】:

  • 这样的代码是可能的,以及使用 onPause 的取消方法中断当前的 AsyncTask,但我不认为这是正确的行为,因为 AsyncTask 正确地完成了他的后台工作,剩下要做的就是关闭当前片段。
【解决方案2】:

使用IntentService 代替AsyncTask 并在onHandleIntent() 中执行您的工作。它是后台并且独立于Fragment's 生命周期,它也可以在工作(后台)线程中工作。

这种方法的一个缺点是来自FragmentActivity 的独立性——你没有Context 并且你不能显示你的Toast。但这是您需要的敏捷性的合理价格,您仍然可以发送Notification 或做任何与Intent 相关的事情 - 开始一个新的Activity 或发送广播。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多