一、概述
Handler这个类主要用来发送和处理消息的。它有多个发送消息函数,但只有一个处理消息函数handleMessage()。
二、要求
程序中有两个线程,一个是UI线程,一个是自己创建的线程,在自己创建的线程中发送消息,在UI线程中接收并处理这个消息。
三、实现
不仅是Android,很多其他界面编程都是不允许在其他线程中直接更新UI界面的。因此可以在其他线程中向UI线程发送一些需要更新界面的消息,让UI线程来更新界面。
新建工程MyHandler,修改/res/layout/main.xml布局文件,在里面添加2个Button按钮,1个空的View(主要是作排版用的)和1个文本TextView。完整的main.xml文件如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical" > 6 7 <Button 8 android:id="@+id/mbutton" 9 android:layout_width="fill_parent" 10 android:layout_height="wrap_content" 11 android:text="启动线程" 12 android:textSize="15px" 13 /> 14 15 <Button 16 android:id="@+id/sbutton" 17 android:layout_width="fill_parent" 18 android:layout_height="wrap_content" 19 android:text="停止线程" 20 android:textSize="15px" 21 /> 22 23 <View 24 android:layout_width="fill_parent" 25 android:layout_height="70px" 26 /> 27 28 <TextView 29 android:id="@+id/mtextview" 30 android:layout_width="fill_parent" 31 android:layout_height="wrap_content" 32 android:text=" " 33 android:textColor="#FF0000" 34 android:textSize="50px" 35 android:gravity="center_horizontal" 36 /> 37 38 </LinearLayout>
接着修改MyHandlerActivity.java文件,该文件中定义了2个类,1个是mHandler类,继承自Handler类,实现了handleMessage (Message msg)函数。另一个是mThread类,继承自Thread类,实现了run()函数。其他那些在程序中都有详细注释,完整的MyHandlerActivity.java文件如下:
1 package com.nan.handler; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.Message; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.TextView; 10 11 public class MyHandlerActivity extends Activity 12 { 13 //线程是否停止标志位 14 private boolean STOP = true; 15 //线程已经启动了几秒 16 private int second = 0; 17 18 private mHandler handler; 19 private mThread thread; 20 private Button mButton; 21 private Button sButton; 22 private TextView mTextView; 23 24 /** Called when the activity is first created. */ 25 @Override 26 public void onCreate(Bundle savedInstanceState) 27 { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.main); 30 31 handler = new mHandler(); 32 thread = new mThread(); 33 34 mTextView = (TextView)findViewById(R.id.mtextview); 35 mButton = (Button)findViewById(R.id.mbutton); 36 //设置“启动线程”按钮事件处理 37 mButton.setOnClickListener(new View.OnClickListener() 38 { 39 40 @Override 41 public void onClick(View v) 42 { 43 // TODO Auto-generated method stub 44 //设置标志位 45 STOP = false; 46 //开启新的线程 47 thread.start(); 48 49 } 50 }); 51 sButton = (Button)findViewById(R.id.sbutton); 52 //设置“停止线程”按钮事件处理 53 sButton.setOnClickListener(new View.OnClickListener() 54 { 55 56 @Override 57 public void onClick(View v) 58 { 59 // TODO Auto-generated method stub 60 //设置标志位 61 STOP = true; 62 } 63 }); 64 65 } 66 67 //自己定义的Handler类 68 private class mHandler extends Handler 69 { 70 @Override 71 public void handleMessage (Message msg) 72 { 73 switch(msg.what) 74 { 75 case 1: 76 { 77 //秒数增加 78 second ++; 79 //显示是第几秒 80 mTextView.setText(Integer.toString(second)); 81 break; 82 } 83 } 84 } 85 } 86 87 //自己定义的Thread类 88 private class mThread extends Thread 89 { 90 91 @Override 92 //线程启动时执行这个函数 93 public void run() 94 { 95 //一直循环,直到标志位为“真” 96 while(!STOP) 97 { 98 try { 99 //延时1秒 100 Thread.sleep(1000); 101 } catch (InterruptedException e) { 102 // TODO Auto-generated catch block 103 e.printStackTrace(); 104 } 105 Message msg = new Message(); 106 //消息标志 107 msg.what = 1; 108 //发送这个消息 109 handler.sendMessage(msg); 110 } 111 } 112 } 113 114 }
好了,运行该程序。
点击一下“开启线程”按钮,如下:
再点击一下“停止线程”按钮,发现计数停止了,说明新开启的线程已经退出了。
完成。