一、Handler介紹
在一個線程中存在一個訊息佇列,當訊息佇列中存在訊息時,Handler就會處理這些訊息;我們考慮一下這種情境:
我們要執行一個耗時很長的業務,執行完後要返回一個結果顯示在TextView上,我們在主線程中執行這種業務是否合理呢?
顯然是不合理的,因此我們會想到把業務放到子線程中執行,但是Android有個規定:所有更新UI的操作全要在主線程中完成,因此我們要做的就是把子線程執行完的結果傳到主線程中並顯示,這就需要Handler的幫忙;
比如ProgressBar、TextView的使用都會用到Handler;
當應用5秒內沒有響應使用者的輸入,則會拋出以下錯誤:
Handler的原理如下:
模板代碼:
package org.xiazdong.handler;public class SampleActivity extends Activity {private Button button;private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {if(msg.what == 1){//更新UI}if(msg.what == 2){//更新UI}}};private OnClickListener listener = new OnClickListener() {class ServiceThread extends Thread{private ServiceListener serviceListener = new ServiceListener() {@Overridepublic void onService(int current) {//服務監聽器//一邊執行,一邊發送訊息給主線程handler.sendMessage(msg);}};@Overridepublic void run() {//執行業務}}@Overridepublic void onClick(View v) {ServiceThread thread = new ServiceThread();//子線程執行業務thread.start();}};@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button = (Button)this.findViewById(R.id.button); button.setOnClickListener(listener); }}
二、執行個體
程式說明:
執行一個業務:從零開始,每隔3秒加1,直到加到5,返回結果5,並通過ProgressBar即時顯示加到幾了;
程式類聲明:
(1)ServiceListener介面:此介面專門用來監聽服務進行,並根據服務進行執行邏輯
- onService(int current);
(2)Service:此類為業務類,執行此業務;
執行效果:點擊開始執行,則每三秒進度條加1,等到進度滿時,顯示result=5;
ServiceListener.java
package org.xiazdong.handler;/** * Service監聽器 * @author xiazdong * */public interface ServiceListener {public void onService(int current);}
Service.java
package org.xiazdong.handler;public class Service {private int sum = 5;private int current = 0;public void sum(ServiceListener listener)throws Exception{while(current<sum){Thread.sleep(3000);current++;listener.onService(current);}}}
MainActivity.java
package org.xiazdong.handler;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;public class MainActivity extends Activity {private TextView textView;private Button button;private ProgressBar progressBar;private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {if(msg.what == 1){int current = msg.getData().getInt("current");progressBar.setProgress(current);}if(msg.what == 2){int result = msg.getData().getInt("result");textView.setText("result="+result);}}};private OnClickListener listener = new OnClickListener() {class ServiceThread extends Thread{private ServiceListener serviceListener = new ServiceListener() {@Overridepublic void onService(int current) {//服務監聽器Message msg = new Message();msg.what = 1;msg.getData().putInt("current", current);handler.sendMessage(msg);}};@Overridepublic void run() {Service service = new Service();progressBar.setMax(5);//設定最大進度progressBar.setProgress(0);//初始進度為0try {service.sum(serviceListener);//執行業務,並傳入監聽器,監聽業務的執行//當執行完成,發送最後的結果5給TextViewMessage msg = new Message();msg.what = 2;msg.getData().putInt("result", 5);handler.sendMessage(msg);} catch (Exception e) {e.printStackTrace();}}}@Overridepublic void onClick(View v) {ServiceThread thread = new ServiceThread();//子線程執行業務thread.start();}};@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView)this.findViewById(R.id.textView); button = (Button)this.findViewById(R.id.button); progressBar = (ProgressBar)this.findViewById(R.id.progressBar); button.setOnClickListener(listener); }}