Android HandlerThread用法

參考文章: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的Looper
Looper 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主線程的交互。

相關文章:

http://blog.csdn.net/shaozg168/article/details/16940687

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章