【问题标题】:Android: Back button press while AsyncTask is runningAndroid:在 AsyncTask 运行时按下后退按钮
【发布时间】:2014-10-17 08:35:23
【问题描述】:

我有一个ActivityA,它有一个按钮。单击button 后,会打开另一个ActivityB

ActivityBonCreate() 方法,我正在启动AsyncTask,它连接到服务器并获取结果并将其显示到屏幕上。

这是Activity B的代码:

public class ActivityB extends Activity {
    AsyncFetch asyncFetch;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(null != savedInstanceState) {
            return;
        }
        asyncFetch = new AsyncFetch();
        asyncFetch.execute();
    }
}


private class AsyncFetch extends AsyncTask<Object, Void, Object> {
    @Override
    protected void onPostExecute(Object o) {

    }

    @Override
    protected Object doInBackground(Object... params) {
        //contacts the http server.
    }
}

在执行AsyncFetch 时,当我回击时,ActivityB 不会立即被破坏。但在AsyncTask 完成后被销毁。

如何实施此操作以避免后按冻结?我在下面尝试过:

@Override
protected void onDestroy() {
    asyncFetch.cancel(true);
    super.onDestroy();
}

但它仍然等待AsyncTask 取消或完成。

就像GMail 应用程序,当我打开某些东西时。在此过程中,如果我按下返回按钮,它就会从Activity 中出来。

还有其他实现后台进程的方法吗?任何design pattern 来实现这个?请告诉我。

感谢任何帮助。

【问题讨论】:

  • 即使按下后键,您是否仍需要来自服务器的响应??
  • 如果实现正确,AsyncTasks 不会阻塞 UI 线程。发布您的完整代码。
  • UI 未被阻止。但在异步完成之前,Activity 不会被销毁。
  • 比你如何体验“后按冻结”?
  • 我经历过,直到异步完成,活动才关闭。

标签: android android-activity android-asynctask


【解决方案1】:

只需处理 onBackPressed() 方法即可:

@Override
public void onBackPressed()
{
    if (asyncFetch != null)
        asyncFetch.cancel(true);

    super.onBackPressed();
}

【讨论】:

    【解决方案2】:

    来自安卓开发者website

    取消任务

    可以通过调用 cancel(boolean) 随时取消任务。调用此方法将导致对 isCancelled() 的后续调用返回 true。调用此方法后,将在 doInBackground(Object[]) 返回后调用 onCancelled(Object),而不是 onPostExecute(Object)。为了确保尽快取消任务,如果可能(例如在循环中),您应该始终定期从 doInBackground(Object[]) 检查 isCancelled() 的返回值。

    简而言之,您可以在onPause()onBackPressed() 中将AsyncTask 标记为已取消,然后在doInBackground() 中添加一些if 块,如果任务是,则立即返回取消。

    例如:

    @Override
    protected void doInBackground(Object... params){
    
        // do some work
    
        if(isCancelled()){
            // end task right away
            return null;
        }
        // if task is not cancelled yet,
        // do some other work
    }
    

    但是,如果网络操作已经开始,您需要从您的HttpClient 取消它。

    【讨论】:

      【解决方案3】:

      试试这个:

      @Override
      public void onBackPressed() {
          asyncFetch.cancel(true);
          // If you want to finish the activity you can use below code
          // finish(); 
      }
      

      【讨论】:

      • 是的,我也尝试过,但行为仍然相同。
      【解决方案4】:

      我们开始吧。试试这个。

      @Override
      public void onBackPressed() {
          if (asyncFetch.getStatus() == AsyncTask.Status.RUNNING) {
             asyncFetch.cancel(true);
          } 
          finish(); 
      }
      

      【讨论】:

      • 你确定你试过没有 super.onBackPressed();一开始?
      • 我尝试了同样的方法,但我仍然看到了问题。仅供参考,我在 AsyncTast 中所做的是 HTTP 通信。我通过 HTTPClient 连接到服务器。在 http 的过程中,后按只需等待 finish() 方法,直到异步任务关闭。
      【解决方案5】:

      当你click后面button,它会先调用onBackPressed(),所以在这部分,取消asynctask

      @Override
      public void onBackPressed() {
          if ( asyncFetch != null && asyncFetch.getStatus() == AsyncTask.Status.RUNNING ){
             asyncFetch.cancel(true);
          } 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-11
        • 1970-01-01
        相关资源
        最近更新 更多