使用Handler搭配Thread
来源:互联网 发布:中国游戏中心mac版 编辑:程序博客网 时间:2024/05/17 09:31
當你希望使用Thread來改變UI View內容的時候就必須要搭配Handler來進行存取。
layout/ ui.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/ProgressDialogSample_ImageView_pImg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/progress_circular_background" /> <ProgressBar android:id="@+id/ProgressDialogSample_ProgressBar_pBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="invisible" /> <TextView android:id="@+id/ProgressDialogSample_TextView_desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@id/ProgressDialogSample_ProgressBar_pBar" android:text="未執行任何步驟。" /></RelativeLayout>
package iamshiao.sample;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.TextView;public class ProgressDialogSample extends Activity { private final int step1 = 1, step2 = 2, step3 = 3, finish = 4; private Thread thread = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ui); //建構執行緒 thread = new Thread(){ @Override public void run(){ try{ doStep1(); doStep2(); doStep3(); Thread.sleep(3000); Message msg = new Message(); msg.what = finish; uiMessageHandler.sendMessage(msg); }catch (Exception e){ e.printStackTrace(); }finally{ } } }; //開始執行執行緒 thread.start(); } private void doStep1() throws InterruptedException{ Thread.sleep(3000); Message msg = new Message(); msg.what = step1; uiMessageHandler.sendMessage(msg); } private void doStep2() throws InterruptedException{ Thread.sleep(3000); Message msg = new Message(); msg.what = step2; uiMessageHandler.sendMessage(msg); } private void doStep3() throws InterruptedException{ Thread.sleep(3000); Message msg = new Message(); msg.what = step3; uiMessageHandler.sendMessage(msg); } //宣告Handler並同時建構隱含類別實體 Handler uiMessageHandler = new Handler(){ @Override public void handleMessage(Message msg){ //讀出ui.xml中的進度光棒 final ProgressBar pBar = (ProgressBar)findViewById( R.id.ProgressDialogSample_ProgressBar_pBar); pBar.setVisibility(View.VISIBLE); //開始後設為可見 //讀出ui.xml中用以表示未開始的圖案 final ImageView pImg = (ImageView)findViewById(R.id.ProgressDialogSample_ImageView_pImg); pImg.setVisibility(View.INVISIBLE); //開始後設為不可見 //讀出ui.xml中的描述用TextView TextView tv = (TextView)findViewById(R.id.ProgressDialogSample_TextView_desc); switch (msg.what){ case step1: tv.setText(R.string.processing_step1); break; case step2: tv.setText(R.string.processing_step2); break; case step3: tv.setText(R.string.processing_step3); break; case finish: tv.setText(R.string.finish); pBar.setVisibility(View.INVISIBLE); pImg.setVisibility(View.VISIBLE); tv.setText("完成。"); thread.interrupt(); break; } super.handleMessage(msg); } };}
執行緒的部分與前篇大致相同,但由於其中不能直接執行
tv.setText(R.string.processing_step1);
這類UI View存取的動作,所以加入了Handler來控制UI View,Handler的運作是利用handleMessage這個事件來監聽執行緒是否有送出Message,如果有的話利用Message的what屬性等機制來判別要進行什麼動作。 例如程式碼中我宣告了4個常數
private final int step1 = 1, step2 = 2, step3 = 3, finish = 4;private void doStep1() throws InterruptedException{ Thread.sleep(3000); Message msg = new Message(); msg.what = step1; uiMessageHandler.sendMessage(msg);}
表示執行緒進行的步驟進度,而執行緒執行副程式doStep1~3的這個過程中,副程式在sleep完成後就會利用Handler變數的sendMessage來送出對應其步驟的Message變數。
//宣告Handler並同時建構隱含類別實體Handler uiMessageHandler = new Handler(){ @Override public void handleMessage(Message msg){ ... switch (msg.what){ case step1: tv.setText(R.string.processing_step1); break; ... } super.handleMessage(msg); }};
最後handleMessage事件再接聽到sendMessage之後就利用Message變數的what屬性之類的機制來判讀、執行對應動作。
重點提醒,使用Thread&Handler要特別注意...
- handleMessage必須有@Override標註表示覆寫。
- 每個Message變數必須重新new,只改動what內容仍會被視為同樣的Message,而造成非預期的錯誤。
Thread.sleep(3000);Message msg = new Message();msg.what = step1;uiMessageHandler.sendMessage(msg);Thread.sleep(3000);msg.what = step2; //X 同Message實體只變更what就重複使用會造成非預期錯誤。uiMessageHandler.sendMessage(msg);Thread.sleep(3000);msg = new Message(); //O Message有重新建構實體才正確。msg.what = step3;uiMessageHandler.sendMessage(msg);
- 任何UI View的控制應該在handleMessage中進行,而不是直接在Thread中進行。
補充
Message變數也可以透過setData方法來攜帶Bundle實體傳遞資料。
Message msg = new Message();Bundle data = new Bundle();data.putString("data", "data");msg.setData(data);msg.what = step2;uiMessageHandler.sendMessage(msg);case step2: tv.setText(msg.getData().getString("data"));
转载地址:http://iamshiao.blogspot.com/2010/12/androidhandlerthread.html
- 使用Handler搭配Thread
- Handler搭配Thread基本用法
- handler thread 使用 2
- 使用Thread、Runnable、Handler
- Thread、Handler与HandlerThread、Handler使用
- Thread、Handler与HandlerThread、Handler使用
- Thread、Handler与HandlerThread、Handler使用
- Thread、Handler与HandlerThread、Handler使用
- Thread、Handler与HandlerThread、Handler使用
- Timer搭配TimerTask与Handler使用(更新UI)
- Android 使用Handler实现Thread间通信
- android handler和thread的使用
- Android 使用Handler实现Thread间通信
- Android 使用Handler实现Thread间通信
- Android-------Handler,Thread,Message使用范例
- android异步处理Handler+Thread使用进阶
- 【安卓笔记】Handler+Thread使用浅析
- android handler和thread的使用
- IOS开发之路-C 学习笔记7.18
- 执行个编码规范真的就那么难吗?
- poj 2407 Relatives(欧拉函数)
- Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
- 【91xcz】WinXP系统内存优化
- 使用Handler搭配Thread
- 项目管理潜规则之加班 Yes/No
- Functional Reactive Programming on iOS with ReactiveCocoa
- MVVM、MVVMLight、MVVMLight Toolkit之我见
- 从郭美美霸气侧漏看项目管理之项目经理防身术
- poj 3897 Maze Stretching (二分+bfs+二维判重)
- iOS7人机界面指南 – ISUX原创翻译
- flex 访问pdf.swf 控制上一页,下一页demo
- 【2013Esri全球用户大会精彩案例】Dartmouth Atlas卫生保健项目-GIS特别贡献奖