【问题标题】:make asynctask return results when time is exceeded超过时间时使异步任务返回结果
【发布时间】:2013-07-04 17:09:24
【问题描述】:

我的应用程序中有一些异步任务在后台执行网络功能(下载/上传文件、http 请求)。在进行这些操作时,我使用ProgressDialog 来显示有关任务进度的消息。但是,某些任务可能需要更多时间才能完成(例如在慢速网络上下载文件),这在应用程序中是不需要的。

如何设置参数来控制每个异步任务的持续时间?无论任务中的作业是否完成,我都希望 asynctask 在某个时候完成。我必须让 asynctask 调用 onPostExecute 方法。

我读到了这个http://developer.android.com/reference/android/os/AsyncTask.html#get%28long,%20java.util.concurrent.TimeUnit%29

这不是很有帮助,因为 UI 会冻结,并且无法实际控制异步任务的持续时间

这是我的代码的一部分

public void downloadFiles(String address) {
        String mainUrl =address;

        //// I overrride the onPostExecute to get
        /// results and call another asynctask
        new Downloader(this){ //<--asynctask
            @Override
            protected void onPostExecute(String result){
                super.onPostExecute(result);
                TestResults=result;

            //another method called that creates another asynctask
             uploadFiles(mainUrl);

            }
        }.execute(mainUrl);


    }

我还尝试使用像 this 这样的处理程序 但它也没有工作。

有没有办法让 asynctask 在一段时间后返回结果(这意味着让 asynctask 调用 onPostExecute 方法)?

在 asnctask 的 doInBackground 方法中使用 while 循环不是解决方案。我想我需要一个来自 mainUI 的计时器来让 asynctask 返回结果。

PS 我的应用程序使用片段,这就是为什么我调用 new Downloader(this) 来从片段传递 gui。

刚刚试过这个:

public void downloadFiles(String address) {
        String mainUrl =address;


        final Downloader tempObject =new Downloader(this){
            @Override
            protected void onPostExecute(String result){
                super.onPostExecute(result);
                downloadResults=result;
                }
        };
        try {
            tempObject.execute(mainUrl).get(3000L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TimeoutException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

这会使 UI 冻结 3 秒,然后触发任务....这不是我想要的。

也试过这个:

Handler handler = new Handler();
        handler.postDelayed(new Runnable()
        {
          @Override
          public void run() {
              if ( tempObject.getStatus() == Downloader.Status.RUNNING )
                  tempObject.cancel(true);
          }
        }, 5000 );

这会导致 asynctask 的 onProgressUpdate 消息停止,但是 asynctask 继续运行......

有什么想法吗?

【问题讨论】:

  • 你是如何下载文件的?我会把超时放在那里,例如:stackoverflow.com/a/3002544/833647
  • 我按照您发布的示例进行操作。问题是传输数据时连接不会断开。例如,当您使用 EDGE netowkr 时,您可能会获得 5-6 KB/秒的速度。连接不会断开,下载可能需要几分钟。当服务器没有响应或没有传输几秒钟时,连接超时。我希望能够确定 asynctask 的持续时间并使其持续不到 30 秒
  • 问题是我想让异步任务有一定的持续时间。在这个时间间隔之后,应该调用 asnctask 的 onPostExecute 方法
  • 嗯,我明白了。然后我猜你发布的 Handler + .get() 方法对我来说似乎是最好的。但这有点违背了 AsyncTask IMO 的目的。抱歉,我没有更好的建议!
  • @KenWolf 我尝试了您所说的方法,但处理程序仅导致消息更新停止。 asynctask 仍在后台执行,消息更新(这是下载文件的百分比条)冻结。我挣扎了好几天。有任何想法吗?提前谢谢!

标签: android android-fragments android-asynctask


【解决方案1】:

Handler 函数的方法需要一些额外的东西来工作。问题的解决方法在于here

AsyncTask 可能会被取消,但doInbackground 方法仍在运行。实际上任务设置为值“取消”,但doInbackgroung 仍将运行直到它完成。为了解决这个问题,我们必须定期在doInbackground 的循环中检查任务是否设置为取消。虽然这不是我想要做的,但这似乎是唯一的解决方案。

doInBackground 中,我们必须检查任务的状态以查看它是否被取消。所以实际上,有人可以在 doInbackground 中使用计时器,让生活更轻松,而无需使用处理程序类。

令人失望的是,不能随意终止同步任务的执行.....如果有人有更好的主意,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多