2013-07-17 211 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,它可以爲您處理所有這些事情。 –