Android - 为AsyncTask设置超时?

Jak*_*son 122 java android android-asynctask

我有一个AsyncTask我执行的类,它从网站下载大量数据.

如果最终用户在使用时数据连接速度非常慢或不稳定,我想AsyncTask在一段时间后进行超时.我的第一个方法是这样的:

MyDownloader downloader = new MyDownloader();
downloader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
  @Override
  public void run() {
      if ( downloader.getStatus() == AsyncTask.Status.RUNNING )
          downloader.cancel(true);
  }
}, 30000 );
Run Code Online (Sandbox Code Playgroud)

启动后AsyncTask,一个新的处理程序被启动,将取消AsyncTask30秒后,如果它仍在运行.

这是一个好方法吗?或者内置的AsyncTask内容是否更适合此目的?

yor*_*rkw 42

是的,有AsyncTask.get()

myDownloader.get(30000, TimeUnit.MILLISECONDS);
Run Code Online (Sandbox Code Playgroud)

请注意,通过在主线程(AKA.UI线程)中调用它将阻止执行,您可能需要在单独的线程中调用它.

  • 如果这个超时方法在主UI线程上运行,似乎就会失败使用AsyncTask的目的...为什么不使用我在问题中描述的`handler`方法?看起来更简单,因为UI线程在等待运行Handler的Runnable时不会冻结...... (7认同)
  • 我不明白为什么你在另一个线程中调用get().它看起来很奇怪,因为AsyncTask本身就是一种线程.我认为Jakobud的解决方案更合适. (3认同)
  • 我知道这是多年以后,但这仍然没有内置到android所以我做了一个支持类.我希望它可以帮助别人.https://gist.github.com/scottTomaszewski/3c9af91295e8871953739bb456de937b (2认同)

小智 17

In the case, your downloader is based upon an for an URL connection, you have a number of parameters that could help you to define a timeout without complex code:

  HttpURLConnection urlc = (HttpURLConnection) url.openConnection();

  urlc.setConnectTimeout(15000);

  urlc.setReadTimeout(15000);
Run Code Online (Sandbox Code Playgroud)

If you just bring this code into your async task, it is ok.

'Read Timeout' is to test a bad network all along the transfer.

'Connection Timeout' is only called at the beginning to test if the server is up or not.


Gil*_*lco 17

在onPreExecute()方法的AsyncTask的扩展类中使用CountDownTimer类:

主要优点是,在类内部完成异步监视.

public class YouExtendedClass extends AsyncTask<String,Integer,String> {
...
public YouExtendedClass asyncObject;   // as CountDownTimer has similar method -> to prevent shadowing
...
@Override
protected void onPreExecute() {
    asyncObject = this;
    new CountDownTimer(7000, 7000) {
        public void onTick(long millisUntilFinished) {
            // You can monitor the progress here as well by changing the onTick() time
        }
        public void onFinish() {
            // stop async task if not in progress
            if (asyncObject.getStatus() == AsyncTask.Status.RUNNING) {
                asyncObject.cancel(false);
                // Add any specific task you wish to do as your extended class variable works here as well.
            }
        }
    }.start();
...
Run Code Online (Sandbox Code Playgroud)

例如,更改CountDownTimer(7000,7000) - > CountDownTimer(7000,1000),它会在调用onFinish()之前调用onTick()6次.如果要添加一些监视,这很好.

感谢您在此页面中获得的所有好建议:-)

  • 但是这将在主UI线程上运行,对吧? (4认同)