參考文章:http://www.cnblogs.com/hnrainll/p/3597246.html
一、HandlerThread簡介
首先我們來看看爲什麼我們要使用HandlerThread?
在我們的應用程序當中爲了實現同時完成多個任務,所以我們會在應用程序當中創建多個線程。爲了讓多個線程之間能夠方便的通信,我們會使用Handler實現線程間的通信。
下面我們看看如何在線程當中實例化Handler。在線程中實例化Handler我們需要保證線程當中包含Looper(注意:UI線程默認包含Looper)。
爲線程創建Looper的方法如下:在線程run()方法當中先調用Looper.prepare()初始化Looper,然後再run()方法最後調用Looper.loop(),這樣我們就在該線程當中創建好Looper。(注意:Looper.loop()方法默認是死循環)
我們實現Looper有沒有更加簡單的方法呢?當然有,這就是我們的HandlerThread。我們來看下Android對HandlerThread的描述。
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
HandlerThread其本質就是一個線程,只是在其run函數內部已經幫我們實現了Looper.prepare以及Looper.loop的操作,其run函數源碼:
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
二、使用步驟
2.1 創建一個HandlerThread,即創建了一個包含Looper的線程。
HandlerThread handlerThread = new HandlerThread("leochin.com");
handlerThread.start(); //創建HandlerThread後一定要記得start()
2.2 獲取HandlerThread的LooperLooper looper = handlerThread.getLooper();
2.3創建Handler,通過Looper初始化Handler handler = new Handler(looper);
通過以上三步我們就成功創建HandlerThread。通過handler發送消息,就會在子線程中執行。三、應用舉例
3.1 使用Handler處理事件
package com.debby.threaddemo;
import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
public class ThreadDemo extends Activity {
private static final String TAG = "bb";
private int count = 0;
private Handler mHandler ;
private Runnable mRunnable = new Runnable() {
public void run() {
//爲了方便 查看,我們用Log打印出來
Log.e(TAG, Thread.currentThread().getId() + " " +count);
count++;
setTitle("" +count);
//每2秒執行一次
mHandler.postDelayed(mRunnable, 2000);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "Main id "+Thread.currentThread().getId() + " " +count);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//通過Handler啓動線程
mHandler = new Handler();
mHandler.post(mRunnable);
}
@Override
protected void onDestroy() {
//將線程與當前handler解除綁定
//mHandler.removeCallbacks(mRunnable);
super.onDestroy();
}
}
最後得到mHandler.post(mRunnable),將執行該Runnable線程體,通過打印得出它其實和UI線程屬於同一線程,如果該線程體中執行的是耗時的操作,將嚴重影響用戶和UI線程的交互。
3.2 使用HandlerThread
public class ThreadDemo extends Activity {
private static final String TAG = "bb";
private int count = 0;
private Handler mHandler ;
private Runnable mRunnable = new Runnable() {
public void run() {
//爲了方便 查看,我們用Log打印出來
Log.e(TAG, Thread.currentThread().getId() + " " +count);
count++;
// setTitle("" +count);
//每2秒執行一次
mHandler.postDelayed(mRunnable, 2000);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "Main id "+Thread.currentThread().getId() + " " +count);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//通過Handler啓動線程
HandlerThread handlerThread = new HandlerThread("threadone");//創建一個handlerThread線程
handlerThread.start();//啓動該線程
mHandler = new Handler(handlerThread.getLooper());//將子線程的消息循環,賦值給主線程的handler
mHandler.post(mRunnable); //加入mRunnable線程體到子線程的消息隊列
}
@Override
protected void onDestroy() {
//將線程與當前handler解除
mHandler.removeCallbacks(mRunnable);
super.onDestroy();
}
}
其實現在的線程體和UI主線程不是同一個線程了,這樣當執行復雜的操作時就不會影響到UI主線程的交互。
相關文章: