android裡面對於非同步訊息的處理,提供了一套Handler的實現方案。Handler有很多適宜的應用和微妙之處,使它在和Thread以及Service等一起使用的時候達到很好的效果。
一. Handler與Thread的區別。Handler與調用者處於同一線程,如果Handler裡面做耗時的動作,調用者線程會阻塞。Android UI操作不是安全執行緒的,並且這些操作必須在UI線程中執行。Android提供了幾種基本的可以在其他線程中處理UI操作的方案,包括Activity的runOnUiThread(Runnable),View的post以及1.5版本的工具類AsyncTask等方案都採用了Handler,Handler的post對線程的處理也不是真正start一個新的線程,而是直接調用了線程的run方法,這正是google煞費苦心搞一套Handler的用意。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startThread();
// sendMessage();
SystemClock.sleep(2000);
setContentView(R.layout.main);
}
public void startThread() {
mThread.start();
}
public void sendMessage() {
MHandler mHandler = new MHandler();
Message msg = mHandler.obtainMessage();
msg.sendToTarget();
}
class MHandler extends Handler {
public MHandler() {
}
public MHandler(Looper l) {
super(l);
}
@Override
public void handleMessage(Message msg) {
int count = 0;
while (count++ MAX_VALUE) {
Log.d(TAG, "Rintail");
}
}
}
Thread mThread = new Thread() {
@Override
public void run() {
int count = 0;
while (count++ MAX_VALUE) {
Log.d(TAG, "Rintail");
}
}
};
二. Handler對於Message的處理不是並發的。一個Looper 只有處理完一條Message才會讀取下一條,所以訊息的處理是阻塞形式的。但是如果用不同的Looper則能達到並發的目的。Service中,onStart的執行也是阻塞的。如果一個startService在onStart執行完成之前,再次條用startService也會阻塞。如果希望能儘快的執行onStart則可以在onStart中使用handler,因為Message的send是非阻塞的。如果要是不同訊息的處理也是並發的,則可以用不同的Looper執行個體化Handler。
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
sendMessageWithLooper();
//sendMessage();
}
public void sendMessage() {
MHandler mHandler = new MHandler();
Message msg = mHandler.obtainMessage();
msg.sendToTarget();
}
public void sendMessageWithLooper() {
HandlerThread ht = new HandlerThread("Rintail");
ht.start();
MHandler mHandler = new MHandler(ht.getLooper());
Message msg = mHandler.obtainMessage();
msg.sendToTarget();
}
class MHandler extends Handler {
public MHandler() {
}
public MHandler(Looper l) {
super(l);
}
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "first");
while (true) {
if (false)
break;
}
Log.d(TAG, "second");
}
};
class MyThread extends Thread {
@Override
public void run() {
Log.d(TAG, "first");
while (true) {
if (false)
break;
}
Log.d(TAG, "second");
}
};
三。 資源回收
向Handler對象發送類似new Message ()形式的空Message可以達到清空Message的目的,這種做法與getLooper().quit()的做法是一樣的。如果利用的資源較多,應及時清理。 |