【问题标题】:Passing a handler from a background Handler Thread, to background thread将处理程序从后台处理程序线程传递到后台线程
【发布时间】:2013-07-17 22:35:28
【问题描述】:

任何人都可以在这里指出正确的方向吗?

我有一个活动,它使用 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 线程中的消息。

【问题讨论】:

  • 将您的活动代码与您调用runnew BasicSearch的代码一起发布

标签: android multithreading handler looper


【解决方案1】:

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

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

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() 中的任何内容。但实际上,您正在做的事情比它需要的复杂得多,而且您几乎肯定只想做我上面提到的事情。

【讨论】:

  • 感谢 Monkeyless。我把它放回 Thread,它实际上不需要 start() 方法。 run() 中的代码在没有执行的情况下执行,它由 LogCat 中的 log.d 输出确认。我稍后会测试你的建议,但你是对的,我可能过于复杂了。我想做的事都可以在一个线程中完成,只需通过处理程序告诉 UI 已经完成。不过,我只是想掌握纯粹使用处理程序进行后台处理的窍门。
  • 啊,不使用处理程序进行后台处理完全没问题,这正是我的示例所做的。通过 bgHandler.post(new Runnable()...) 传递的任何可运行对象都将在后台线程上执行。我的意思是,为了创建和使用后台线程,您不需要自己扩展 Thread 或创建/调用 Looper。相反,您可以使用我展示的 HandlerThread,它会为您处理所有这些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-07
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
  • 1970-01-01
  • 2016-01-27
  • 2011-02-09
相关资源
最近更新 更多