2013-07-17 212 views
0

任何人都可以在此向我指出正确的方向吗?从后台处理程序线程传递处理程序到后台线程

我有派生两个线程的活动,处理邮件,用活套

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,但是当我发送消息时它仍然最终为null。

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

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

我已经成功设法在我的UI线程中使用了一个处理程序,但是我的当前项目在UI中进行的处理过多,我想要一个辅助线程处理searchThread的输出,并且只接收线程完成时UI线程中的消息。

+0

将您的活动代码与您称为'run'和'new BasicSearch'的代码一起发布。 – njzk2

回答

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()中的任何内容。实际上,你所做的事情就是,它需要变得更加复杂,而且你几乎可以肯定地只是做我上面提到的。

+0

感谢Monkeyless。我把它放回线程,它实际上不需要start()方法。 run()中的代码在LogCat中没有执行,由log.d输出确认。我稍后会测试你的建议,但你说得对,我可能过于复杂。我想要做的事情都可以在一个线程中完成,而UI只是通过一个处理程序被告知它已完成。尽管如此,我只想纯粹使用处理程序来处理后台处理。 –

+0

啊,没有使用处理程序进行后台处理是完全正确的,这正是我的例子所做的。任何通过bgHandler.post(new Runnable()...)传递的runnable将在后台线程上执行。我的意思是,为了创建和使用后台线程,您不需要扩展线程或自己创建/调用一个Looper。相反,您可以像我所示的那样使用HandlerThread,它可以为您处理所有这些事情。 –