0

有人可以在这里指出我正确的方向吗?

我有一个使用 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();
    }

...然后它产生主工作线程,它从 UI 线程传递一个处理程序,以及来自上述线程的处理程序。

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");

}

    }

不管发生什么,当它尝试 dispatchMessage 时,handlerMiddleThread 将恢复为 null。我什至在我的活动中有以下代码,以尝试确保它不为空,但当我发送消息时它仍然最终为空。

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

这是一个测试项目,因为我希望在继续我的项目之前能够正确理解 Handler/Looper 的概念。

我之前已经成功地在我的 UI 线程中使用了一个处理程序,但是我当前的项目在 UI 中进行了太多的处理,我希望有一个辅助线程来处理来自 searchThread 的输出,并且只在 UI 中收到一条消息线程完成时线程。

4

1 回答 1

2

所以我想我明白你在做什么,让我建议一个更简单的方法:

启动后台线程并获取处理程序:

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

然后你可以向你的 bgHandler 发送你想要的任何消息。请注意,您需要在创建 bgThread 之前在 HandlerThread 上调用 start(否则 getLooper() 将返回 null)。

话虽如此,我想我知道您发布的代码有什么问题。首先,MiddleThread 扩展了 Handler(它没有 run() 方法!)而不是 Thread。其次,MiddleThread 上的 run() 方法永远不会被调用,因此 Handler 永远不会被实例化。即使您只是在上面的代码中输入了错误的 Handler 并且您实际上是在扩展 Thread,您仍然需要在 MiddleThread 上调用 start 才能执行 run() 中的任何内容。确实,您正在做的事情比它需要的要复杂得多,而且您几乎肯定只想做我上面提到的事情。

于 2013-07-17T14:35:28.227 回答