Handler类的主要作用有两个:

  • 在新启动的线程中发送消息。
  • 在主线程中获取、处理消息。

上面的说法很简单,只要分成两步即可:在新启动的线程中发送消息;然后在主线程上获取、并处理消息。但这个过程涉及一个问题:新启动的线程何时发送消息呢?主线程何时去获取并处理消息呢?这个时机显然不好控制。

为了让主程序能“适时”地处理新启动的线程所发送的消息,显然只能通过回调的方式来实现——开发者只要重写Handler类中处理消息的方法,当新启动的线程发送消息时,消息会发送到与之关联的MessageQueue,而Handler会不断地从MessageQueue中获取并处理消息——这将导致Handler类中处理消息的方法被回调。

Handler类包含如下方法用于发送、处理消息。

  • void handleMessage(Message msg):处理消息的方法。该方法通常用于被重写。
  • final boolean  hasMessages(int what):检查消息队列中是否包含what属性为指定值的消息。
  • final boolean  hasMessages(int what,Object object):检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息。
  • sendEmptyMessage(int what):发送空消息。
  • final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定多少毫秒之后发送空消息。
  • final boolean sendMessage(Message msg):立即发送消息。
  • final boolean sendMessageDelayed(Message msg,long delayMillis):指定多少毫秒之后发送消息。

借助于上面这些方法,程序可以方便地利用Handler来进行消息传递。

    实例:自动播放动画

      上面的程序通过一个新线程来周期性地修改ImageView所显示的图片,通过这种方式来开发一个动画效果。该程序的界面布局代码非常简单,程序只是在界面布局中定义了ImageView组件,界面布局文件如下。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<!-- 定义ImageView组件 -->
<ImageView
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"/> </LinearLayout>

接下来主程序使用java.util.Timer来周期性地执行指定任务,程序代码如下。

package com.example.studyevent;

import java.util.Timer;
import java.util.TimerTask; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.ImageView; public class HandlerTest extends Activity {
//定义周期性显示的图片的ID
int[] imageIds=new int[]{
R.drawable.java,
R.drawable.ee,
R.drawable.ajax,
R.drawable.xml,
R.drawable.classic
};
int currentImageId=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_test);
final ImageView show=(ImageView)findViewById(R.id.show);
final Handler myHandler=new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
//如果该消息是本程序所发送的
if(msg.what==0x1233)
{
//动态地修改所显示的图片
show.setImageResource(imageIds[currentImageId++%imageIds.length]);
}
}

};
//定义一个计时器,该计时器周期性的执行指定任务
new Timer().schedule(new TimerTask(){
@Override
public void run() {
// TODO Auto-generated method stub
//发送空消息
myHandler.sendEmptyMessage(0x1233);
}
}, 0,1200
);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.handler_test, menu);
return true;
} }

上面的程序中下面的粗体字代码通过Timer周期性地执行指定任务,Timer对象可调度TimerTask对象,TimerTask对象的本质就是启动一条新线程,由于Android不允许在新线程中访问Activity里面的界面组件,因此程序只能在新线程里发送一条消息,通知系统更新ImageView组件。

上面的程序的第一段粗体字代码重写了Handler的handleMessage(Message msg)方法,该方法用于处理消息——当新线程发送消息时,该方法会被自动回调,handleMessage(Message msg)方法依然位于主线程,所以可以动态地修改ImageView组件的属性。这就实现了本程序所要达到的效果;由新线程来周期性地修改ImageView的属性,从而实现动画效果。运行上面的程序可看到应用程序中5张图片交替显示的动画效果。

最新文章

  1. 《Entity Framework 6 Recipes》中文翻译系列 (23) -----第五章 加载实体和导航属性之预先加载与Find()方法
  2. struts2学习笔记--使用Validator校验数据
  3. 用于基于 RPM 的 Linux 平台的 Java
  4. Android中View类OnClickListener和DialogInterface类OnClickListener冲突解决办法
  5. OpenCV的安装与系统环境变量
  6. c++ 爬虫
  7. python仿微软记事本
  8. 容器的end()方法
  9. jQuery对象和DOM对象原来不一样啊
  10. json与字符串互转
  11. Oracle数据库时间类型悬疑案
  12. 通过 pxe(网络安装)完成centos 系统的网络安装
  13. Servlet编程实例2
  14. WebService简单介绍(一)
  15. C#导出文本内容到word文档源码
  16. SLES Install
  17. verilog HDL-参数型数据对像 与‘define
  18. SQLServer导数据到Oracle
  19. 深入理解Linux内核-系统调用
  20. elasticsearch 分布式集群搭建

热门文章

  1. Linux操作系统入门教程
  2. HDU 5487 Difference of Languages(BFS)
  3. Python中super的用法
  4. Total Highway Distance
  5. PAT (Advanced Level) 1082. Read Number in Chinese (25)
  6. hbase 第一篇
  7. mysql忘记密码及无法使用程序连接
  8. OSX下编译安装opencv3.1.0与opencv_contrib_master
  9. HDU 5620 KK&#39;s Steel
  10. CodeForces 625D Finals in arithmetic