Android 避免非法国家例外“;onSaveInstanceState”之后无法执行此操作;

Android 避免非法国家例外“;onSaveInstanceState”之后无法执行此操作;,android,android-fragments,android-asynctask,Android,Android Fragments,Android Asynctask,这个话题有很多不同的问题,我知道,但是我认为大多数人在问问题的时候仍然不明白为什么事情会发生 我已经阅读了关于的文章,尽管他为所有事情都提供了明确的论据(阅读这篇文章——这篇文章内容丰富且易于理解),但他并没有为我的情况提供全面的证明——使用AsyncTasks 以下是我们在应用程序中的操作: 用户按下一个按钮,启动一个AsycTask调用我们的服务器 使用Intent.ACTION\u call从应用程序内部发起电话呼叫 电话通话结束,用户返回应用程序 AsyncTask以服务器调用响应进行响

这个话题有很多不同的问题,我知道,但是我认为大多数人在问问题的时候仍然不明白为什么事情会发生

我已经阅读了关于的文章,尽管他为所有事情都提供了明确的论据(阅读这篇文章——这篇文章内容丰富且易于理解),但他并没有为我的情况提供全面的证明——使用
AsyncTask
s

以下是我们在应用程序中的操作:

  • 用户按下一个按钮,启动一个
    AsycTask
    调用我们的服务器
  • 使用
    Intent.ACTION\u call
    从应用程序内部发起电话呼叫
  • 电话通话结束,用户返回应用程序
  • AsyncTask
    以服务器调用响应进行响应
  • 应用程序代码处理响应并向用户显示输出
  • 显然,当用户拨打电话时,我们的应用程序就会停止。因此,当
    AsyncTask
    到达
    onPostExecute()
    并提供服务器调用响应时,我们可能没有处于活动状态,并且可能是在调用了
    onSaveInstanceState()
    之后

    那么我该如何解决这个问题呢

    我必须通过
    AlertDialogFragment
    将服务器调用响应的结果传达给用户,但是当我想要显示该警报时,我会得到IllegalStateException

    Alex Lockwood建议我确保在调用
    OnSaveInstanceState()
    后不会发生碎片事务,即(我图)不要从
    AsycTask的
    onPostExecute()
    触发应用程序中的任何东西(如显示警报)

    那什么时候呢

    我应该在
    onResume()
    中做些什么,比如检查我是否收到了来自
    AsyncTask
    服务器调用的响应,我可能应该将响应保存到共享的prefs中,而不是处理并向用户显示结果,如果是,则向用户显示该警报


    请告知?

    在导航到
    活动
    后,
    异步任务
    仍将运行。这意味着当
    活动
    不再可见时,可以调用
    onPostExecute()
    ,并且应该在
    onPostExecute()
    中进行的任何UI更改都将导致
    异常
    ,很可能是
    NullPointerException
    非法状态异常

    要解决此问题,您必须通过在活动的
    onPause()
    中停止并在活动的
    onResume()
    中重新启动
    AsyncTask
    来自己管理
    AsyncTask
    ,或者将任务放在保留的非UI
    片段中。在我看来,这些解决方案有点老套。我强烈建议在任务执行后修改UI时,使用
    AsyncTaskLoader
    代替
    AsyncTask
    。AsyncTaskLoader使用
    LoaderManager
    ,它为您处理活动/片段生命周期

    有许多资源演示了AsyncTaskLoader的正确实现,我在下面列出了其中一些资源:

    我在一个开源应用程序CrimeTalk Reader中使用了
    AsyncTaskLoader
    类,使用Jsoup加载web数据,并将结果放在
    列表视图中。可以在上找到使用它的类


    如果希望在没有UI交互的情况下运行长时间运行的任务,则可能需要签出该类。

    是否尝试过使用AsyncTaskLoader?我知道这并不能回答你的问题,但我不久前放弃了异步任务,因为它们在面对活动生命周期的各个方面时会带来很多问题。这可能值得一读:否则请确保在onPostExecute()中执行各种空检查,以确保在前台没有活动的情况下不会显示AlertDialog。嗨,John,我一直在阅读AsyncTaskLoader。谢谢你的提示!看来我们需要解决这个问题。我认为我们仍然会在应用程序的某些区域使用AsyncTask,因为当您希望根据任务执行的内容进行UI更改时,建议使用AsyncTaskLoader。谢谢哦,如果您将此解决方案作为答案发布,我会将其标记为正确的,如果经过测试并证明是一个解决方案。:)杰出的我一到电脑就起草一份答案。