我的AsyncTask应该等到UI线程中的事件发生。
所以,我开始有简单的while循环。但是,在某些导致 UI 线程冻结的设备中。所以在阅读以下答案后:挂起时致命旋转/卡在线程 ID 上[但是,它并不完全相同 - 我将 while 放在异步任务中而不是在主活动中]
我添加了Thread.sleep - 它似乎确实解决了这个问题。
但是,我觉得我在这里做错了什么...我想知道正确的方法是什么。
永远不要休眠或阻塞 UI 线程。在 AsyncTask 的后台线程中等待。
一种方法是 suitianshi 用 wait((/notifyAll(( 指出的那样。另一个是使用CountDownLatch:
- 在 UI 线程中创建一个闩锁:
CountDownLatch latch = new CountDownLatch(1);
- 子类
AsyncTask
,以便它在构造函数中获取闩锁并将其保存到引用mLatch
- 在
doInBackground()
,当您需要等待时,请拨打mLatch.await()
。这将阻止AsyncTask
- 在 UI 中,当您正在等待的事件发生时,请调用
latch.countDown()
你应该很高兴从这里开始。
我的意见会有所不同...
my AsyncTask should wait till event in the UI-thread happen.
AsyncTask非常适合长时间运行的操作,如http下载,长时间的I/O操作,图像大小调整或任何会冻结UI线程的CPU密集型操作。
但是,Android 按顺序运行 AsyncTasks,默认情况下不在池中运行。 更多细节在这里。
因此,如果你有一个无限期运行的 AsyncTask,例如等待 UI 操作,你可能会阻止其他 AsyncTasks 运行。 导致更多的死锁和线程问题。
我会建议以下任何一项:
为您的 AsyncTask 使用不同的执行器,使其运行方式与现在类似,但不与其他 AsyncTask 项目冲突。这是最简单的方法。
将 AsyncTask 拆分为多个任务。第一个执行您当前的 AsyncTask 所做的一切,直到等待。 第二个执行当前在 UI 事件后执行的操作。后一个任务由生成事件的 UI 排队。
使用专用线程。根据需要,使用 Handler 类将事件从线程编组回 UI 线程。
AsyncTask是为运行需要很长时间的事情而引入的。在早期的安卓操作系统中,它可以在主线程或 UI 线程中完成。但是现在 android 迫使我们在 AsyncTask 中做长时间运行的事情,以使 UI 线程响应。如果你想在AsyncTask期间你的android UI什么都不做,那么你可以简单地添加进度对话框。在onPreExecute()
中开始进度对话框,在onPostExecute(String[] result)
中结束。
示例代码:在异步任务中
@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
}
谢谢