Specifics on using Looper.prepare() in Android
Asked Answered
A

2

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?

Adjunct answered 13/7, 2011 at 3:17 Comment(0)
V
7

What's going on is that once you call Looper.prepare() followed by Looper.loop() on a Thread, all that Thread will ever do is service its MessageQueue until someone calls quit() on its Looper.

The other thing to realize is that, by default, when a Handler is instantiated, it's code will always execute on the Thread it was created on

What you should do is create a new Thread and in run() call Looper.prepare(), setup any Handlers, and then call Looper.loop().

Bearing these things in mind here is the basic pattern I use a lot of places. Also, there's a good chance you should just be using AsyncTask instead.

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
    }
}
Vicariate answered 21/7, 2011 at 23:20 Comment(0)
J
0

Could you tell some examples for what you are using your network thread? I think you can solve your problems without using Looper.

You can use ASyncTask to perform background task that may update some values in your UI thread. If user has to wait until background operation will be finished, you can show ProgressDialog and block application in OnPreExecute method, and then hide it in onPostExecute.

As I said, please describe more your needs and target which you want to achieve.

Jurist answered 18/7, 2014 at 11:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.