Android:当AsyncTask在运行时按返回按钮

8

我有一个名为ActivityA的活动,其中有一个按钮。点击该button后,它会打开另一个ActivityB

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

这是ActivityB的代码:

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

是否有其他实现后台处理的方法?有没有实现这个的设计模式?请告诉我。

任何帮助都将不胜感激。


即使按下返回键,您是否仍需要从服务器获取该响应? - Elltz
如果正确实现,AsyncTasks不会阻塞UI线程。请发布您的完整代码。 - biegleux
UI没有被阻塞,但是Activity在异步完成之前不会被销毁。 - User12111111
你有没有遇到过“后退键冻结”的情况? - biegleux
我经历过,只有在异步完成后,活动才会关闭。 - User12111111
你是怎么解决这个问题的?我也遇到了同样的问题,下面的所有答案都对我没用。 - carefree
5个回答

4

只需要处理onBackPressed()方法:

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

    super.onBackPressed();
}

3

来自安卓开发者官网

取消任务

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

简而言之,在您的ActivityonPause()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取消它。


2

试试这个:

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

是的,我也试过了,但行为仍然一样。 - User12111111

1

我们开始吧。试试这个。

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

1
你确定在开始时没有尝试过不使用super.onBackPressed()吗? - Remees M Syde
我尝试了相同的方法,但问题仍然存在。顺便说一下,我在AsyncTask中进行的是HTTP通信。我通过HTTPClient连接到服务器。在http过程中,返回按钮只会等待finish()方法直到异步任务关闭。 - User12111111

-1

当您单击返回按钮时,它首先调用onBackPressed(),因此在此部分中,取消asynctask

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接