曾經在開發 Android 系統的過程中,遇到了一個強制

要把 Handler 加入 looper 的情況。是因為一個 Dialog 跑在 

另一個 thread 導致 Android 丟出 Exception。

 

為這個 Dialog 的 Handler 加上 looper 之後,便迎刃而解。

在遇到這個 Error 之前,其實壓根不知道 looper 的作用為何。

但其實簡單的說,如果要在 Handler 裡頭再加 Handler,

記得要把它用 Looper 放入 Pipe line 裡頭(開另一條線程)。

 

到底 Looper 與 Handler 的用途與關係為何?

 

 看了一篇英文介紹文章,有些恍然大悟的感覺,在這裡分享給大家。

 

Looper 主要的用途是把 Thread 轉變成 Pipe line,可以說是另開一條線程去跑,

這樣就不會影響主線程的運行。

 

而 Handler 是把線程加入一些 message 讓開發者可以利用發送 message

來控制此線程。

 

在 Looper 把 Thread 轉入 Pipe line 時,並不需要設定什麼參數,

方法大致如下:

 

@Override
public void run() {
  try {
    // preparing a looper on current thread    
    // the current thread is being detected implicitly
    Looper.prepare();
 
    // now, the handler will automatically bind to the
    // Looper that is attached to the current thread
    // You don't need to specify the Looper explicitly
    handler = new Handler();
     
    // After the following line the thread will start
    // running the message loop and will not normally
    // exit the loop unless a problem happens or you
    // quit() the looper (see below)
    Looper.loop();
  } catch (Throwable t) {
    Log.e(TAG, "halted due to an error", t);
  }
}

可以觀察到的是,這是一個 Thread 裡發生的事情,

然後把一個 Handler 的前後加上 

 

Looper.prepare();

Looper.loop();

 

此 Handler 的 thread 就會自動另起一條線。

並不需要指令什麼參數或者名稱,就不會和外面的 Thread 跑在一起。

 

可以想見,我們還會有另外一段 Code 有關於另外一條 Thread 會做的事情。

1
2
3
4
5
6
handler.post(new Runnable() {
  @Override
  public void run() {      
    // this will be done in the Pipeline Thread      
  }
});

莫約像是這一段的形式,所以這一段做的事情就會再 Pipe line裡跑了!

 

而其實開發者不需要知道到底再哪個 Thread 裡跑,只需要確保

它是跑在另一條線程當中即可。

 

另外就是可能會有人有疑問:那為什麼在類似 onCreate() 這種主線程裡,

卻不需要加 Looper?

 

答案是,已經加了只是省略沒顯示而已啦~

1
2
3
4
5
6
7
8
9
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
     
    // Create the Handler. It will implicitly bind to the Looper
    // that is internally created for this thread (since it is the UI thread)
    handler = new Handler();
}

若是像上面的這段常見的寫法,這個 Handler 裡的動作其實早已經

被放在另一個線程上面了。

 

因為 Android 這類型的行動裝置,為求使用者體驗極佳,

嚴格要求主線程順利運行,所以多了很多規劃 Threads 的工具,

像是 Looper 與 Handler 其實都要比過去純 Java 的方法好用!

 

 主要參照以下網址翻譯並重整

http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/

arrow
arrow
    全站熱搜

    keep walking 發表在 痞客邦 留言(0) 人氣()