Handler消息机制

Handler的定义:
          主要接受子线程发送的数据, 并用此数据配合主线程更新UI.
          解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。  如果此时需要一个耗时的操作,例如: 联网读取数据,    或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示  "强制关闭".  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的. 这个时候,Handler就出现了.,来解决这个复杂的问题 ,    由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

本程序功能: 利用Handler实现时间和图片的持续更新  

xml文件:

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" 
 6     android:gravity="center_horizontal">
 7 
 8     <ImageView 
 9         android:id="@+id/iv"
10         android:layout_width="wrap_content"
11         android:layout_height="wrap_content"
12         android:src="@drawable/ic_launcher"/>
13     <TextView 
14         android:id="@+id/tv"
15         android:layout_width="wrap_content"
16         android:layout_height="wrap_content"
17        />
18 </LinearLayout>
View Code

 

java代码如下:

  1 import java.text.SimpleDateFormat;
  2 import java.util.Date;
  3 import java.util.Timer;
  4 import java.util.TimerTask;
  5 
  6 import android.annotation.SuppressLint;
  7 import android.app.Activity;
  8 import android.os.Bundle;
  9 import android.os.Handler;
 10 import android.os.Message;
 11 import android.widget.ImageView;
 12 import android.widget.TextView;
 13 
 14 @SuppressLint("SimpleDateFormat")
 15 public class HanderActivity extends Activity {
 16     // 控制时间的更新
 17     private static final int Time = 1;
 18     // 控制图片的更新
 19     private static final int Imge = 2;
 20     private ImageView iv;
 21     private TextView tv;
 22     private int index = 0;
 23     private int[] sorce = { R.drawable.img1, R.drawable.img2, R.drawable.img3,
 24             R.drawable.img4, R.drawable.img5, R.drawable.img6, R.drawable.img7,
 25             R.drawable.img8 };
 26     private SimpleDateFormat format = new SimpleDateFormat(
 27             "yyyy年-MM月-dd日  HH时:mm分:ss秒");
 28 
 29     /* (non-Javadoc)
 30      * @see android.app.Activity#onCreate(android.os.Bundle)
 31      */
 32     @SuppressLint("HandlerLeak")
 33     @Override
 34     protected void onCreate(Bundle savedInstanceState) {
 35         super.onCreate(savedInstanceState);
 36         setContentView(R.layout.activity_hander);
 37         iv = (ImageView) findViewById(R.id.iv);
 38         tv = (TextView) findViewById(R.id.tv);
 39 
 40         
 41         // Android应用中,我们页面都是主线程或UI线程中进行呈现,如果我们在我们UI线程中进行耗时性操作的话,我们UI线程就会出现ANR(Application
 42         // not respose),所以我们要子线程中进行耗时性操作内容,但是这样有不容易触及我们UI控件,所以Android提供了Handler,用于在主线程和子线程之间传递和接受消息
 43         
 44 
 45         final Handler hander = new Handler() {
 46             //重写handlerMessage()方法
 47             @Override
 48             public void handleMessage(Message msg) {
 49                 if (msg.what == Time) {
 50                     Bundle data = msg.getData();
 51                     String time = data.getString("time");
 52                     tv.setText(time);
 53                 } else if (msg.what == Imge) {
 54                     Bundle data = msg.getData();
 55                     int image = data.getInt("img");
 56                     iv.setImageResource(sorce[image]);
 57                 }
 58             }
 59 
 60         };
 61         //    开启一个子线程,用于进行耗时的操作,完成后向hander发送数据
 62         //此线程是控制时间更新的
 63         new Thread() {
 64             public void run() {
 65                 while (true) {
 66                     Message msg = new Message();
 67                     //指定类型
 68                     msg.what = Time;
 69                     Bundle b = new Bundle();
 70                     //向Bundle中放入数据
 71                     b.putString("time", format.format(new Date()));
 72                     //指定数据
 73                     msg.setData(b);
 74                     //向handler发送数据
 75                     hander.sendMessage(msg);
 76                     try {
 77                         //每隔一秒更新一次时间
 78                         sleep(1000);
 79                     } catch (InterruptedException e) {
 80                         e.printStackTrace();
 81                     }
 82                 }
 83             };
 84 
 85         }.start();
 86         
 87         /**开启一个定时器,用于定时更新图片的。
 88          *第一个参数:类似Runnable接口
 89             第二个参数:第一次执行延迟多久
 90             第三个参数:就是以后执行的周期,多长时间执行一次
 91          */
 92         new Timer().schedule(new TimerTask() {
 93 
 94             @Override
 95             public void run() {
 96                 /**防止数组下标越界,如果达到最大值让index重新置为0,*/
 97                 if (index == sorce.length) {
 98                     index = 0;
 99                 }
100                 Message msg = new Message();
101                 msg.what = Imge;
102                 Bundle b = new Bundle();
103                 b.putInt("img", index);
104                 msg.setData(b);
105                 hander.sendMessage(msg);
106                 index++;
107 
108             }
109         }, 0, 1000);
110 
111     }
112 
113 }

  运行的效果是:图片和时间每隔一秒就会变化一次。

posted @ 2013-10-29 16:25  用户没有名  阅读(214)  评论(0编辑  收藏  举报