将runnable发布到UI线程直到完成后调用wait()

时间:2013-11-24 18:29:14

标签: java android multithreading

在我的应用程序线程可以继续之前,我实际上需要等待ui线程执行runnable。 wait()/ notify()方式是一种正确的方法,还是有更好的方法呢?我实际上在做什么看起来像这样:

public void showVideoView() {
    try {
        final AtomicBoolean done = new AtomicBoolean(false);
        final Runnable task = new Runnable() {
            @Override
            public void run() {
                synchronized(this) {
                    mStartupCurtain.setVisibility(View.GONE);
                    mVideoView.setVisibility(View.VISIBLE);
                    mWebView.loadUrl("about:blank");
                    mWebView.setVisibility(View.GONE);
                    done.set(true);
                    notify();
                }
            }
        };
        mUiHandler.post(task);
        synchronized(task) {
            while(!done.get()) {
                task.wait();
            }
            Log.d(TAG, "showVideoView done!");

        }
    } catch (InterruptedException e) {
        Log.e(TAG, "Thread got interrupted while waiting for posted runnable to finish its task");
    }

}

当我这样做时,我必须确保该线程不是UI之一,当我从一个来自MediaPlayer.OnCompletionListener之类的接口的侦听器方法调用方法时会发生这种情况。

您怎么看?

2 个答案:

答案 0 :(得分:1)

使用AsyncTask!

  

AsyncTask可以正确,轻松地使用UI线程。这个班   允许执行后台操作并在UI上发布结果   线程,而不必操纵线程和/或处理程序。

http://developer.android.com/reference/android/os/AsyncTask.html

答案 1 :(得分:1)

对我来说很好。

“done”变量可以是常规布尔值而不是AtomicBoolean,因为您最终在锁定内获取/设置它的值。我喜欢你在调用wait之前检查“done”的值 - 因为在你在worker线程中输入锁之前很可能完成了任务。如果你还没有这样做,那么wait()调用将无限期地发生,因为notify()已经发生了。

有一个边缘情况需要考虑,可能适用于您的设计,也可能不适用。当工作线程仍在等待任务完成时,如果UI线程试图退出(即app退出)会发生什么?另一种变化是当工作线程在等待任务完成时,但UI线程正在等待工作线程退出。后者可以用另一个布尔变量来解决,UI线程通过该布尔变量通知工作线程退出。这些问题可能相关也可能不相关 - 取决于UI如何管理线程开始。