6

I'm having a bit of trouble understanding how to use the Looper prepare()/loop()/quit() logic.

I have three threads: one is the UI thread, one is a game logic thread and the last is a network communication thread (a background thread, lives only while being used).

The game thread has many dependencies on the results of the network calls, so I wanted to spin the network thread off of the game thread and have a Handler post the result back.

Of course, since the UI thread is not involved I need to call Looper.prepare()... somewhere. I thought it should be called in the game thread, but I can't do that because loop() takes it over.

How do I go about posting back to the game thread from network thread with my handler?

4

2 回答 2

7

发生的事情是,一旦你在一个线程上调用 Looper.prepare(),然后是Looper.loop (),线程将要做的就是服务它的 MessageQueue,直到有人在它的 Looper 上调用 quit()。

要实现的另一件事是,默认情况下,当 Handler 被实例化时,它的代码将始终在创建它的 Thread 上执行

你应该做的是创建一个新线程并在 run() 中调用 Looper.prepare(),设置任何处理程序,然后调用 Looper.loop()。

记住这些是我在很多地方使用的基本模式。此外,您很有可能应该只使用 AsyncTask 。

public class NetworkThread extends Thread {
    private Handler mHandler;
    private Handler mCallback;
    private int QUIT = 0;
    private int DOWNLOAD_FILE = 1;
    public NetworkThread(Handler onDownloaded) {
        mCallback = onDownloaded;
    }

    public void run() {
        Looper.prepare();
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    // things that this thread should do
                    case QUIT:
                        Looper.myLooper().quit();
                        break;
                    case DOWNLOAD_FILE:
                        // download the file
                        mCallback.sendMessage(/*result is ready*/);
                }
            }
        }
        Looper.loop();
    }

    public void stopWorking() {
        // construct message to send to mHandler that causes it to call 
        // Looper.myLooper().quit
    }

    public void downloadFile(String url) {
        // construct a message to send to mHandler that will cause it to
        // download the file
    }
}
于 2011-07-21T23:20:01.360 回答
0

你能告诉一些你使用网络线程的例子吗?我认为您可以在不使用 Looper 的情况下解决您的问题。

您可以使用ASyncTask执行后台任务,该任务可能会更新您的 UI 线程中的某些值。如果用户必须等到后台操作完成,您可以在 OnPreExecute 方法中显示ProgressDialog并阻止应用程序,然后在 onPostExecute 中将其隐藏。

正如我所说,请描述更多您的需求和您想要实现的目标。

于 2014-07-18T11:55:41.103 回答