因为Android平台不同意Activity新启动的线程訪问该Activity里的界面控件。这样就会导致新启动的线程无法动态改变界面控件的属性值。但在实际Android应用开发中,尤其是涉及动画的游戏开发中,须要让新启动的线程周期性地改变界面控件的属性值,这就须要借助Handler的消息传递机制实现。
一、Handler类简单介绍
1.功能
Handler类主要有两个作用
(1)在新启动的线程中发送消息;
(2)在主线程中获取消息、处理消息。即当须要界面发生变化的时候。在子线程中调用Handler类的sendEmptyMessage()方法或sendMessage方法来发送消息到Handler。为了让主线程能"适时"地处理新启动的线程所发送的消息,可採用回调的方式来实现--仅仅需重写Handler类中处理消息的方法,当新启动的线程发送消息时。Handler类中处理消息的方法会被自己主动调用。
2.Hnadler类经常用法
方法 |
描 述 |
public void handleMessage (Message msg) |
通过该方法获取、处理消息 |
public final boolean sendEmptyMessage (int what) |
发送一个仅仅含有what标记的空消息 |
public final boolean sendMessage (Message msg) |
发送消息到Handler,通过handleMessage()方法接收和处理 |
public final boolean hasMessages (int what) |
监測消息队列中是否包括标记为what的消息 |
public final boolean post (Runnable r) |
将一个线程对象加入到消息队列 |
二、Handler消息传递程序开发步骤
(1)创建一个Handler类对象,并重写handleMessage()方法(用于获取、处理消息);
(2)在新启动的线程中,调用Handler对象的发送消息方法;
(3)利用Handler对象的handleMessage()方法接收消息。然后依据不同的消息运行不同的操作。
注意:发送和处理消息的是同一Handler对象。即自己发送,自己处理。
三、源代码实战
实现:实现一个动态变化的随机数效果。
(1)HandlerTest.java
package com.example.android_handler; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; public class HandlerTest extends Activity { int i=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView text = (TextView)findViewById(R.id.random); //1.创建一个Handler类对象,并重写handleMessage()方法 final Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==0x520) { text.setText("获得的新随机数为:\n"+Math.random()); } } }; //2.定义一个计时器。让该计时器以1.2s周期性地运行指定任务(毫秒为基本单位) // new Timer().schedule(new TimerTask(){ // public void run() { // handler.sendEmptyMessage(0x520); // } // }, 0, 1200); new Thread(new Runnable(){ public void run() { while(true) { try { Thread.sleep(1200); } catch (Exception e) { e.printStackTrace(); } handler.sendEmptyMessage(0x520); } } }).start(); } }
(2)layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/random" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="35dp" android:layout_gravity="center"/> </LinearLayout>
效果演示:
源代码分析:通过以上实例。我们知道在子线程发送消息时能够採用两种方法
a.定时器
new Timer().schedule(new TimerTask()
{
public void run()
{
......功能代码.....
}
}
b.子线程延时
new Thread(new Runnable()
{
public void run()
{
while(true)
{
Thread.sleep(1200);
......功能代码.....
}
}
}).start();
该方法有两点须要注意,一是假设希望程序不停的发送消息,则须要通过while(true)将功能代码包含起来。二是当子线程创建成功后,须要调用Thread的start()方法来启动该子线程。