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

问题描述:

我的AsyncTask应该等到UI线程中的事件发生。什么是从UI线程暂停AsyncTask的正确方法

所以,我开始有简单的while循环。但是,在导致UI线程冻结的一些设备中。所以阅读下面的答案后: Fatal Spin-On-Suspend/Stuck on ThreadID [然而,这是不太一样的 - 我把在异步任务的,而不是在主要活动]

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

但是,我觉得我在这里做错了什么......我想知道什么是正确的做法。

+0

为什么不使用'object.wait()'? – suitianshi 2014-08-29 09:18:49

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

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

  1. 在UI线程创建锁:CountDownLatch latch = new CountDownLatch(1);
  2. 子类AsyncTask因此,它需要一个锁存器在构造函数并将其保存到一个参考mLatch
  3. doInBackground(),当你需要等待电话mLatch.await()。这将阻止用户界面中的AsyncTask
  4. ,当你在等待的事件发生时,调用latch.countDown()

你要善于从这里走。

+1

谢谢。我会研究这一点 – 2014-08-29 14:27:12

AsyncTask被引入运行需要很长时间的东西。在较早的android操作系统中,它可以在主线程或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 
    } 

感谢

我的意见将是不同的......

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

的AsyncTask的是伟大的喜欢长时间运行的操作HTTP下载,长I/O操作,调整图像大小,或将冻结任何CPU密集型操作UI线程。

但是,默认情况下,Android按顺序运行AsyncTasks,而不是在池中运行。 More details here

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

我建议以下任何一项:

  1. 使用不同Executor您的AsyncTask所以它运行今天同样因为它,但不与其他的AsyncTask项目发生冲突。这是最简单的方法。

  2. 将您的AsyncTask分成多个任务。第一个不管你现在的AsyncTask做什么,直到等待。第二个在你的UI事件之后做你现有的任何事情。后面的任务由生成事件的用户界面排队。

  3. 使用专用线程。根据需要使用Handler类将事件从线程回收到UI线程。