Android中handler的作用與線程
Android handler 的主要用途根據官網上的解釋,可以概括為兩點:
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
也就是說handler保存了兩個隊列,一個消息隊列,一個runnable隊列,handler負責順序一個一個執行兩個隊列里需要處理的元素。首先需要強調一下,handler并不是開辟了一個新的線程去執行,而是在其調用線程中,這個可以用以下代碼去測試:
package com.relin.handler;import android.app.Activity; import android.os.Bundle; import android.os.Handler;
public class AndroidHandlerActivity extends Activity { /* Called when the activity is first created. /
private Handler handler = new Handler(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); handler.post(r); System.out.println("Activity-------->"+Thread.currentThread().getId()); System.out.println("Activityname----->"+Thread.currentThread().getName()); } Runnable r = new Runnable(){ @Override public void run(){ System.out.println("handler-------->"+Thread.currentThread().getId()); System.out.println("hanldername----->"+Thread.currentThread().getName()); try{ Thread.sleep(5000); }catch(Exception e){ } } };
}</pre>
上述代碼首先定義了一個Runable對象,但是handler.post(r)并沒有開辟新的線程,很容易發現,handler實際上使用的線程就是主線程。當然我們也可以用自定義一個線程,讓handler在另一個線程中執行,這樣主線程不會因為handler中有大量工作需要處理而進入阻塞狀態:
package com.relin.bundle;import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message;
public class AndroidBundleActivity extends Activity { /* Called when the activity is first created. / @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.out.println("activity----->" + Thread.currentThread().getId()); //由android系統內核提供,其中有一個looper專門用于處理消息隊列 HandlerThread handlerThread = new HandlerThread("handler_thread"); //在使用getLooper之前,必須先調用start,不然looper是null handlerThread.start(); MyHandler myHandler = new MyHandler(handlerThread.getLooper()); Message msg = myHandler.obtainMessage(); Bundle b = new Bundle(); b.putInt("age", 20); b.putString("name", "relin"); msg.setData(b); msg.sendToTarget(); }
class MyHandler extends Handler{ public MyHandler(){ } public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Bundle b = msg.getData(); int age = b.getInt("age"); String name = b.getString("name"); System.out.println("age is " + age + ", name is " + name); System.out.println("handler----->" + Thread.currentThread().getId()); } }
}</pre>