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



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

所以,我开始有简单的while循环。但是,在某些导致 UI 线程冻结的设备中。所以在阅读以下答案后:挂起时致命旋转/卡在线程 ID 上[但是,它并不完全相同 - 我将 while 放在异步任务中而不是在主活动中]

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

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

永远不要休眠或阻塞 UI 线程。在 AsyncTask 的后台线程中等待。

一种方法是 suitianshi 用 wait((/notifyAll(( 指出的那样。另一个是使用CountDownLatch:

  1. 在 UI 线程中创建一个闩锁:CountDownLatch latch = new CountDownLatch(1);
  2. 子类AsyncTask,以便它在构造函数中获取闩锁并将其保存到引用mLatch
  3. doInBackground(),当您需要等待时,请拨打mLatch.await()。这将阻止AsyncTask
  4. 在 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 运行。 导致更多的死锁和线程问题。

我会建议以下任何一项:

  1. 为您的 AsyncTask 使用不同的执行器,使其运行方式与现在类似,但不与其他 AsyncTask 项目冲突。这是最简单的方法。

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

  3. 使用专用线程。根据需要,使用 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
    }

谢谢

相关内容

最新更新