1. 程式人生 > >常用的兩種handler呼叫方法

常用的兩種handler呼叫方法

一、Handler、Thread、HandlerThread三者之間的關係如下:

1、Handler:在android中負責傳送和處理訊息,通過它可以實現其他支線執行緒與主執行緒之間的訊息通訊。

2、Thread:Java程序中執行運算的最小單位,亦即執行處理機排程的基本單位。某一程序中一路單獨執行的程式。

3、HandlerThread:一個繼承自Thread的類HandlerThread。
二、Handler跟Thread結合使用,首先在FirstHandler.java類中建立要在介面呼叫的getSum方法,具體實現如下:
 

package com.example.handlerdemo;

import android.os.Handler;
import android.os.Message;

public class FirstHandler {

	private Handler mHandler;
	public static final int ADD_FLAG = 1;
	public void setHandler(Handler handler){
		mHandler = handler;
	}
	
	public synchronized void getSum(final int a, final int b){
		Logger.d("a = " + a + " ,b = " + b);
		class AddRunThread implements Runnable{

			@Override
			public void run() {
				Logger.d("FirstHandler ThreadId = " + Thread.currentThread().getId());
				int sum = add(a, b); 
				try {
					Thread.sleep(6 * 1000); //模擬加法運算是一個非常複雜的運算,所以要開執行緒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				String result = "result = " + sum;
				Message message = mHandler.obtainMessage();
				message.what = ADD_FLAG;
				message.obj = result;
				mHandler.sendMessage(message); //在新的執行緒中進行傳送Message訊息
			}
		}
		Thread addRun = new Thread(new AddRunThread());
		addRun.setPriority(Thread.MAX_PRIORITY); //設定執行緒優先順序
		addRun.start();//執行緒啟動
	}
	/**
	 * 實現加法運算
	 */
	private int add(int a, int b){
		return a + b;
	}
}

當呼叫 getSum方法的時候會先啟動addRun執行緒,addRun執行緒啟動後就會執行AddRunThread類裡面的run方法,run方法裡面執行了一個加法運算的add方法,然後會執行Thread.sleep(6 * 1000)來模擬耗時的操作。加法運算add方法實行結束後會通過mHandler.sendMessage(message)來通知介面更新資訊。接下來看一下介面MainActivity的實現,具體如下:

package com.example.handlerdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;


public class MainActivity extends Activity {
	private TextView textView;
	private FirstHandler firstHandler;
	private SecondHandler secondHandler;
	private String result;
	
	private Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			Logger.d("Handler ThreadId = " + Thread.currentThread().getId());
			switch (msg.what) {
			case FirstHandler.ADD_FLAG:
				Logger.d("FirstHandler.ADD_FLAG");
				textView.setText((String) msg.obj); //更新加法運算後的結果
				break;
			case SecondHandler.UI_REFLESH:
				Logger.d("SecondHandler.UI_REFLESH"); 
				textView.setText((String) msg.obj); //更新減法運算後的結果
				break;
			default:
				break;
			}
		};
	};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Logger.d("main ThreadId = " + Thread.currentThread().getId());
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tx_show);
        firstHandler = new FirstHandler();
        secondHandler = new SecondHandler();
    }

    /*
     * handler跟Thread結合使用的測試方法
     */
    public void addCheck(View view){
    	Logger.d();
    	firstHandler.setHandler(handler); //設定Handler物件例項
    	firstHandler.getSum(3000, 4600);  //呼叫FirstHandler類的getSum方法
    }
    
    /*
     * handler跟HandlerThread結合使用的測試方法
     */
    public void decreaseClick(View view){
    	Logger.d();
    	secondHandler.getSerialThread().post(new Runnable() {
			
			@Override
			public void run() {
				Logger.d("SecondHandler ThreadId = " + Thread.currentThread().getId());
				int sum = decrease(300, 180);
				try {
					Thread.sleep(8 * 1000); //模擬減法運算是一個非常複雜的運算,所以要開執行緒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				result = "result2 = " + sum;
				Message message = new Message();
				message.what = SecondHandler.UI_REFLESH;
				message.obj = result;
				handler.sendMessage(message); //通過主執行緒更新UI
			}
		});
    }
    
    //減法運算
    private int decrease(int a, int b){
    	return a - b;
    }
    
}

 可以看到在handleMessage中進行了訊息處理,當msg.what等於FirstHandler.ADD_FLAG時,就會將加法運算的結果設定到textView中展示。

 

三、handler跟HandlerThread結合使用。程式碼邏輯主要在SecondHandler.java類中實現,具體如下:

package com.example.handlerdemo;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;

public class SecondHandler {
	
	public Handler uiHandler = new Handler(Looper.getMainLooper()); //main主執行緒,由於更新UI更新
	private HandlerThread mHandlerThread;
	private Handler handler;
	public static final int UI_REFLESH = 0X02;
	
	//設定handler物件關聯
	public void setUIhandler(Handler handler){
		uiHandler = handler;
	}
	
	/**
	 *獲取獲得Looper物件的Handler例項
	 */
	public synchronized Handler getSerialThread(){
		if (null == mHandlerThread){
			HandlerThread thread = new HandlerThread("work_thread");//工作執行緒,用於耗時的操作,不能用於更新UI
			thread.start();
			handler = new Handler(thread.getLooper()){
			};
		}
		return handler;
	}
}

通過 new Handler(thread.getLooper())來建立handler跟HandlerThread的聯絡。接下來看一下具體怎麼呼叫getSerialThread()方法,如下:

 /*
     * handler跟HandlerThread結合使用的測試方法
     */
    public void decreaseClick(View view){
    	Logger.d();
    	secondHandler.getSerialThread().post(new Runnable() {
			
			@Override
			public void run() {
				Logger.d("SecondHandler ThreadId = " + Thread.currentThread().getId());
				int sum = decrease(300, 180);
				try {
					Thread.sleep(8 * 1000); //模擬減法運算是一個非常複雜的運算,所以要開執行緒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				result = "result2 = " + sum;
				Message message = new Message();
				message.what = SecondHandler.UI_REFLESH;
				message.obj = result;
				handler.sendMessage(message); //通過主執行緒更新UI
			}
		});
    }
    
    //減法運算
    private int decrease(int a, int b){
    	return a - b;
    }

首先通過 getSerialThread()方法獲取secondHandler物件,然後呼叫了post方法,在run方法中執行了減法decrease(300, 180)運算,減法運算結束後會呼叫一個休眠函式Thread.sleep(8 * 1000),休眠8秒來模擬是耗時操作,休眠結束後會通過主執行緒的handler來通知介面更新減法的結果。執行結果如下: