天天看點

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