2

我有一些代码来创建一个新线程,然后在该线程中创建一个处理程序和循环器。然后调用线程可以发布到这个处理程序:

class MyClass {

    Handler mHandler = null;
    Thread mThread = null;

    MyClass() {
        mThread = new Thread() {
            public void run() {
                Looper.prepare();
                mHandler = new Handler();
                Looper.loop();
            }
        };

        mThread.start();

        /* ... */

        mHandler.post(...);
    }
}

此代码几乎直接来自文档中的示例。但我不明白它怎么可能是正确的。因为 mHandler 是在子线程中初始化的,所以不能保证什么时候发生。是什么阻止了这段代码在最后一行发布到 null 处理程序?

如果此代码不正确,那么以同步方式在新创建的线程上创建处理程序的方法是什么?

4

3 回答 3

1

最简单的方法是使用 HandlerThread:

class MyClass {

    final Handler mHandler = null;
    final HandlerThread mThread = null;

    MyClass() {
        mThread = new HandlerThread("...");
        mThread.start();
        mHandler = new Handler(mThread.getLooper());

        /* ... */

        mHandler.post(...);
    }
}

这缩短了同步问题,因为 looper 是在 Thread.start() 内部创建的,因此处理程序可以链接到父线程中的该 looper。

于 2012-08-27T06:29:13.100 回答
0

在您的示例中,什么是 Looper(它在哪里声明)?线程是轻量级进程,它们在进程中创建并共享其数据。一个线程又可以创建一个新线程(子线程),该线程又可以创建另一个线程,依此类推。你可能想看看mutexes、locks 和 semaphores

您可以使用标志(一组线程可见)来确定它们的行为。

于 2012-08-12T22:56:11.367 回答
0

我会用这种方式来完成这项工作,我认为它不是最好的,只是想知道更多关于它的好主意,所以我把它扔掉了。

mThread = new Thread() {

    public void run() {
        Looper.prepare();
        mLooper = Looper.myLooper();
        mHandler = new Handler();
        Looper.loop();
        }
    };

mThread.start();

......
timeout = 0;
mHandler2 = new Handler ();
DetectHandlerIsReady detect = new DetectHandlerIsReady ();
detect.run ();

class DetectHandlerIsReady implements Runnable {
    public void run ()
    {
         if (mHandler != null) { 
              mHandler.post (....);
         } else if (timeout <= 30) {
              timeout++;
              mHandler2.postDelay (detect, 1000);
              return;
         } 

         // timeout, and mHandler is not ready yet
    }
}
于 2012-08-12T22:50:45.997 回答