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张图片交替显示的动画效果。

Handler消息传递机制——Handler类简洁的更多相关文章

  1. Handler消息传递机制——Handler、Loop、MessageQueue的工作原理

    为了更好地理解Handler的工作原理,先介绍一下与Handler一起工作的几个组件. Message:Handler接收和处理的消息对象. Looper:每个线程只能拥有一个Looper.它的loo ...

  2. 事件处理机制与Handler消息传递机制

    一.基于监听的事件处理机制 基于监听的时间处理机制模型: 事件监听机制中由事件源,事件,事件监听器三类对象组成 处理流程如下: Step 1:为某个事件源(组件)设置一个监听器,用于监听用户操作 St ...

  3. 安卓开发_深入理解Handler消息传递机制

    一.概述 因为子线程的run()方法无法修改UI线程(主线程)的UI界面,所以Android引入了Handler消息传递机制,实现在新创建的线程中操作UI界面 二.消息类(Message) 消息类是存 ...

  4. Android学习笔记-事件处理之Handler消息传递机制

    内容摘要:Android Handler消息传递机制的学习总结.问题记录 Handler消息传递机制的目的: 1.实现线程间通信(如:Android平台只允许主线程(UI线程)修改Activity里的 ...

  5. Handler消息传递机制

    引言: 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题. 为了解决这个问题,Android制定了一条简单的规则:只允许UI线程 ...

  6. Android学习之Handler消息传递机制

    Android只允许UI线程修改Activity里的UI组件.当Android程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户 ...

  7. 解析Android的 消息传递机制Handler

    1. 什么是Handler: Handler 网络释义"机械手.经理"意思,在Android它用于管理多个线程UI操作: 2. 为什么会出现Handler: 在Android里面的 ...

  8. Android中的消息机制:Handler消息传递机制

    参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...

  9. 3.3 线程---Handler消息传递机制浅析

    Handler的执行流程图: 当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送信息;而我们发送的信息会先到主线程的MessageQueu ...

随机推荐

  1. 关于NIOS ii烧写的几种方式

    1. 方法一:.sof和.elf全部保存在FPGA内,程序加载和运行也是在FPGA内部. 把FPGA的配置文件.sof通过JTAG方式下载(其实是在线运行)进入FPGA本身,此时在NIOS II的界面 ...

  2. Fruit Feast

    Fruit Feast 题目描述 Bessie has broken into Farmer John's house again! She has discovered a pile of lemo ...

  3. 【BZOJ3524/2223】[Poi2014]Couriers 主席树

    [BZOJ3524][Poi2014]Couriers Description 给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大 ...

  4. Windows Azure Table Storage 解决 Guid 查询问题

    在使用 Windows Azure Table Storage 的 CloudTableClient 对Azure 进行数据查询时,会发现在自定义类的Guid类型始终无法去成功查询出数据,对比发现 G ...

  5. spring3mvc与struts2比较

    目前企业中使用SpringMvc的比例已经远远超过Struts2,那么两者到底有什么区别,是很多初学者比较关注的问题,下面我们就来对SpringMvc和Struts2进行各方面的比较: 1. 核 心控 ...

  6. angularJS 系列(三)- 自定义 Service

    参考:http://viralpatel.net/blogs/angularjs-service-factory-tutorial/ https://www.pluralsight.com/blog/ ...

  7. iOS ZBar扫码简单实现

    导入ZBarSDK文件并引入一下框架 AVFoundation.framework CoreMedia.framework CoreVideo.framework QuartzCore.framewo ...

  8. IOS_FMDB有关字典、数组存储及获取问题

    http://blog.csdn.net/betterbb/article/details/25984455 FMDB存储字典或数组时会变成字符串存入sqlite里,但如果不将其转换成json格式存储 ...

  9. RDA5820收音机芯片驱动

    RDA5820 是北京锐迪科推出的一款集成度非常高的立体声 FM收发芯片.该芯片具有以下 特点:   FM 发射和接收一体   支持 65Mhz~115Mhz的全球 FM接收频段,收发天线共用. ...

  10. IOS即时通讯XMPP搭建openfire服务器

    一.下载并安装openfire 1.到http://www.igniterealtime.org/downloads/index.jsp下载最新openfire for mac版 比如:Openfir ...