从UI线程暂停AsyncTask的正确方法是什么

时间:2014-08-29 09:04:09

标签: android

我的AsyncTask应该等到UI线程中的事件发生。

所以,我开始有简单的while循环。但是,在某些导致UI线程冻结的设备中。所以看完以下答案后: Fatal Spin-On-Suspend/Stuck on ThreadID [但是,它并不完全相同 - 我把时间放在async-task而不是主要活动中]

我添加了Thread.sleep - 它似乎确实解决了这个问题。

然而,我觉得我在这里做错了什么......我想知道做对照的方法是正确的。

3 个答案:

答案 0 :(得分:3)

不要睡觉或阻止UI线程。等待AsyncTask的后台线程。

一种方法是,suitianshi指出wait()/ notifyAll()。另一个是使用CountDownLatch:

  1. 在UI线程中创建一个锁存器:CountDownLatch latch = new CountDownLatch(1);
  2. 子类AsyncTask,以便在构造函数中使用锁存器并将其保存到引用mLatch
  3. 当你需要等待电话doInBackground()时,mLatch.await()中的
  4. 。这将阻止AsyncTask
  5. 在用户界面中
  6. ,当您正在等待的事件发生时,请致电latch.countDown()
  7. 你应该很高兴离开这里。

答案 1 :(得分:1)

我的观点会有所不同......

my AsyncTask should wait till event in the UI-thread happen.

AsyncTask非常适合长时间运行的操作,如http下载,长I / O操作,图像大小调整或任何会冻结UI线程的CPU密集操作。

但是,Android默认按顺序运行AsyncTasks而不是池。 More details here

因此,如果您有一个无限期运行的AsyncTask,例如等待UI操作,则可能会阻止其他AsyncTasks运行。导致更多的死锁和线程问题。

我会建议以下任何一项:

  1. 为AsyncTask使用不同的Executor,因此它的运行方式与现在类似,但不会与其他AsyncTask项冲突。这是最简单的方法。

  2. 将AsyncTask拆分为多个任务。第一个执行当前AsyncTask在等待之前所执行的操作。第二个执行UI事件后当前的操作。后一个任务由生成事件的UI排队。

  3. 使用专用线程。使用Handler类将事件从线程重新编组回UI线程。

答案 2 :(得分:0)

AsyncTask是为了运行需要很长时间的东西而引入的。在早期的Android OS中,它可以在主线程或UI线程中完成。但现在android迫使我们在AsyncTask中做长时间运行以使UI线程响应。如果你想在AsyncTask期间你的Android UI什么都不做,那么你可以在它期间简单地添加进度对话框。 onPreExecute()&中的开始进度对话框在onPostExecute(String[] result)结束。

示例代码:在AsyncTask中

@Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(MainActivity.this);
        dialog.setMessage("Loading, please wait...");
        dialog.setIndeterminate(true);
        dialog.show();
    }
@Override
    protected void onPostExecute(String[] result) {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }
        // do something with result
    }

由于