2011-08-08 51 views
1

我有一個耗時的任務(迭代通過文件和發送它的內容到服務器),我想執行在後臺線程,在特定interwal(這就是爲什麼我想使用處理程序)。困惑與線程 - 處理程序塊UI線程

從UI線程我有這樣一個電話:

LogsManager lm; 
lm = new LogsManager(this); 
lm.processLogFiles(); 

而在LogsManager類我有下面這段代碼:

public void processLogFiles(){ 
    Handler mHandler = new Handler(); 
    mHandler.postDelayed(logsRunable, 1000);  
} 

private Runnable logsRunable = new Runnable() { 
     @Override 
     public void run() { 
      File f = new File(Environment.getExternalStorageDirectory()+Constants.LOG_DIR);    
      File[] logFiles = f.listFiles(); 
      for (int i = 0; i < logFiles.length; i++) { 
       readLogs(logFiles[i]); // executes some other methods inside 
      } 
     } 
    }; 

正如你可以看到它只是法Handler調用Runnable。而且,不幸的是,它也阻止了我的UI線程。是不是Handler應該爲Runnable啓動一個新線程?我也在我的應用程序的其他部分使用處理程序,並且它們工作得很好。我做錯了什麼?

回答

7

正如the docs指出,Handler

當你創建一個新的處理程序,它必然這是創造它

所以,如果你在UI線程建立mHandler線程的線程/消息隊列,然後它會運行在UI線程的任務 - 因此這個問題。

+0

所以,基本上我必須爲Handler創建帶runnable的線程? – Sver

+0

@Sver我認爲你並不需要'Handler'。您可以創建單個線程或更好地使用http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html來完成工作 –

+0

謝謝! ScheduledExecutorService工作正常,並且更易於理解。 – Sver

0

我認爲你應該使用AsyncTask類來達到這個目的。

計劃執行特定延遲後的任務,你的情況是1000

+0

爲什麼?順便說一句,我不更新任何用戶界面元素。 – Sver

+0

因爲你的UI線程將被掛起,除非它完成耗時的後臺任務 – Rasel

2

Handler的所有post *方法都在Handler的原始線程上運行代碼(在您的情況下爲GUI線程)。如果你想要一個後臺線程,你需要明確地啓動一個(見下文)或使用AsyncTask,如果你需要更新GUI。

Thread t = new Thread(logsRunable); 
t.start(); 
0

我也認爲AsyncTask是一個很好的解決方案,您的情況。