Douglas Brett
Douglas Brett

Reputation: 171

Passing a handler from a background Handler Thread, to background thread

Can anyone point me in the right direction here please ?

I have an activity which spawns two threads, a thread for handling messages, using a Looper

    public static class MiddleThread extends Handler{
    static public Handler handler;

    public void run() {
        Looper.prepare();
        Log.d("MiddleThread", "Looper is prepared !");
        handler = new Handler() {

            public void handleMessage(Message msg)
            {
                Bundle bundle = msg.getData();
                String exitString = bundle.getString("endmessage");
                if(exitString.equals(("ExitOK")))
                {
                    boolean searchFinished = true;
                    Looper looper = Looper.myLooper();
                    looper.quit();
                } else
                {
                    int fileCount = bundle.getInt("filecount");
                    String fileName = bundle.getString("filename");
                    Log.d("MiddleThread", "File Number " + fileCount + " is " + fileName);
                }
            }
        };
        Log.d("MiddleThread", "nandler should be initialised");
        Looper.loop();
    }

... then it spawns the main Worker Thread, which is passed a handler from the UI Thread, and the handler from the above thread.

public class BasicSearch {
public Handler handlerUi, handlerMiddleThread;
public Message messageUi, messageMiddleThread;
public int fileCount = 0;
public BasicSearch(Handler ui, Handler mt) {
    handlerUi = ui;
    handlerMiddleThread = mt;
}

public void listFiles()
{
    File searchPath = Environment.getExternalStorageDirectory();
    messageUi = handlerUi.obtainMessage();
    messageMiddleThread = handlerMiddleThread.obtainMessage();
    walk(searchPath);
    Bundle b = new Bundle();
    b.putString("endmessage", "ExitOK");
    messageMiddleThread.setData(b);
    handlerMiddleThread.dispatchMessage(messageMiddleThread);
}

private void walk(File path) {
    File[] list = path.listFiles();
    for(File f : list)
    {
        if(f.isDirectory())
        {               
            walk(new File(f.getAbsolutePath()));
        } else {
            processFile(f);
        }
    }
}

private void processFile(File f) {
    Bundle b = new Bundle();
    fileCount++;
    b.putString("filename", f.getName());
    b.putInt("filecount", fileCount);
    messageMiddleThread.setData(b);
    Log.d("BasicSearch", "Data is set, to send to MiddleThread");
    handlerMiddleThread.dispatchMessage(messageMiddleThread);
    Log.d("BasicSearch", "Message sent");

}

    }

Whatever happens, when it tries to dispatchMessage, handlerMiddleThread reverts to being null. I even have the following code in my activity, to try and ensure that it isn't null, but it still ends up being null when I get to send the message.

      startMiddleThread();
    while(true)
    {
        if(MiddleThread.handler != null)
            break;
    }   
    startSearchThread();

This is a test project, as I wanted to be able to get the Handler/Looper concept properly understood before continuing on with my project.

I have successfully managed to use a Handler in my UI Threads before, but my current project has too much processing going on in the UI, and I want to have a secondary thread handling the output from the searchThread, and just receive a message in UI thread when the thread is complete.

Upvotes: 0

Views: 2763

Answers (1)

Sam Judd
Sam Judd

Reputation: 7387

So I think I see what you're trying to do and let me suggest a slightly easier way:

To start your background thread and get a handler to it:

HandlerThread bgThread = new HandlerThread();
bgThread.start();
Handler bgHandler = new Handler(bgThread.getLooper());

Then you can send whatever messages you want to your bgHandler. Note that you need to call start on a HandlerThread before creating the bgThread (otherwise getLooper() will return null).

That being said I think I know whats wrong with your code as you posted it. First, MiddleThread extends Handler (which doesn't have a run() method!) not Thread. Second, the run() method on MiddleThread is never called, so Handler is never instantiated. Even if your just mistyped Handler in your code above and you're actually extending Thread, you still need to call start on MiddleThread in order for anything in run() to be executed. Really though, what you're doing is waaay more complicated that it needs to be, and you almost certainly want to just do what I mentioned above.

Upvotes: 2

Related Questions