Android Handler消息传递机制

1. Handler消息传递机制初步认识:什么是Handler?
handler通俗一点讲就是用来在各个线程之间发送数据的处理对象。在任何线程中,只要获得了另一个线程的handler,则可以通过 handler.sendMessage(message)方法向那个线程发送数据。基于这个机制,我们在处理多线程的时候可以新建一个thread,这个thread拥有UI线程中的一个handler。当thread处理完一些耗时的操作后通过传递过来的handler向UI线程发送数据,由UI线程去更新界面。
主线程:运行所有UI组件,它通过一个消息队列来完成此任务。设备会将用户
的每项操作转换为消息,并将它们放入正在运行的消息队列中。主线程位于一个循环中,并处理每条消息。如果任何一个消息用时超过5秒,Android将抛出
ANR。所以一个任务用时超过5秒,应该在一个独立线程中完成它,或者延迟处理它,当主线程空闲下来再返回来处理它。

2.常用类:(Handler、Looper、Message、MessageQueue)
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现
handleMessage(Message
msg)方法来对特定的Message进行处理,例如更新UI等。Handler类的主要作用:(有两个主要作用)1)、在工作线程中发送消息;2)、在
主线程中获w/取、并处理消息。
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message串联起来的,等待Looper的抽取。
Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

3.Handler、Looper、Message、MessageQueue之间的关系:

  • Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue;
  • 而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue;
  • 在一个线程中,只能有一个Looper和MessageQueue,但是可以有多个Handler,而且这些Handler可以共享一个Looper和MessageQueue;
  • Message被存放在 MessageQueue中,一个 MessageQueue中可以包含多个Message对象

【备注:】
Looper对象用来为一个线程开启一个消息循环,从而操作MessageQueue;
默认情况下,Android创建的线程没有开启消息循环Looper,但是主线程例外。
系统自动为主线程创建Looper对象,开启消息循环;
所以主线程中使用new来创建Handler对象。而子线程中不能直接new来创建Handler对象就会异常。
子线程中创建Handler对象,步骤如下:
Looper.prepare();
Handler handler = new Handler() {
//handlemessage(){}
}
Looper.loop();

4.Handler类中常用方法:
(1) handleMessage() 用在主线程中,构造Handler对象时,重写handleMessage()方法。该方法根据工作线程返回的消息标识,来分别执行不同的操作。
(2) sendEmptyMessage() 用在工作线程中,发送空消息。
(3) sendMessage() 用在工作线程中,立即发送消息。

5.Message消息类中常用属性:
(1) arg1 用来存放整型数据
(2) arg2 用来存放整型数据
(3) obj 用来存放Object数据
(4) what 用于指定用户自定义的消息代码,这样便于主线程接收后,根据消息代码不同而执行不同的相应操作。

上一下Demo的示例代码:

private Handler handler = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text_main_info = (TextView) findViewById(R.id.text_main_info);
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Loading...");
        image_main = (ImageView) findViewById(R.id.image_main);

        // 主线程中的handler对象会处理工作线程中发送的Message。根据Message的不同编号进行相应的操作。
        handler = new Handler() {
                public void handleMessage(android.os.Message msg) {
                        // 工作线程中要发送的信息全都被放到了Message对象中,也就是上面的参数msg中。要进行操作就要先取出msg中传递的数据。
                        switch (msg.what) {
                        case 0:
                                // 工作线程发送what为0的信息代表线程开启了。主线程中相应的显示一个进度对话框
                                pDialog.show();
                                break;
                        case 1:
                                // 工作线程发送what为1的信息代表要线程已经将需要的数据加载完毕。本案例中就需要将该数据获取到,显示到指定ImageView控件中即可。
                                image_main.setImageBitmap((Bitmap) msg.obj);
                                break;
                        case 2:
                                // 工作线程发送what为2的信息代表工作线程结束。本案例中,主线程只需要将进度对话框取消即可。
                                pDialog.dismiss();
                                break;
                        }
                }
        };

        new Thread(new Runnable() {
                @Override
                public void run() {
                        // 当工作线程刚开始启动时,希望显示进度对话框,此时让handler发送一个空信息即可。
                        // 当发送这个信息后,主线程会回调handler对象中的handleMessage()方法。handleMessage()方法中
                        // 会根据message的what种类来执行不同的操作。
                        handler.sendEmptyMessage(0);

                        // 工作线程执行访问网络,加载网络图片的任务。
                        byte[] data = HttpClientHelper.loadByteFromURL(urlString);
                        // 工作线程将网络访问获取的字节数组生成Bitmap位图。
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                                        data.length);
                        // 工作线程将要发送给主线程的信息都放到一个Message信息对象中。
                        // 而Message对象的构建建议使用obtain()方法生成,而不建议用new来生成。
                        Message msgMessage = Message.obtain();
                        // 将需要传递到主线程的数据放到Message对象的obj属性中,以便于传递到主线程。
                        msgMessage.obj = bitmap;
                        // Message对象的what属性是为了区别信息种类,而方便主线程中根据这些类别做相应的操作。
                        msgMessage.what = 1;
                        // handler对象携带着Message中的数据返回到主线程
                        handler.sendMessage(msgMessage);

                        // handler再发出一个空信息,目的是告诉主线程工作线程的任务执行完毕。一般主线程会接收到这个消息后,
                        // 将进度对话框关闭
                        handler.sendEmptyMessage(2);
                }
        }).start();
}
时间: 2025-01-03 18:44:39

Android Handler消息传递机制的相关文章

Android Handler消息传递机制详解

1.为什么要用Handler 出于性能优化的考虑,Android UI操作并不是线程安全,如果有多个线程并发操作UI组件,可能导致线程安全问题.可以设想下,如果在一个Activity中有多个线程去更新UI,并且都没有加锁机制,可能会导致什么问题? 界面混乱,如果加锁的话可以避免该问题但又会导致性能下降.因此,Android规定只允许UI线程修改Activity的UI组件.当程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,比如用户

解析Android的 消息传递机制Handler

1. 什么是Handler: Handler 网络释义"操纵者,管理者的"意思,在Android里面用于管理多线程对UI的操作: 2. 为什么会出现Handler: 在Android的设计机制里面,只允许主线程(一个程序第一次启动时所移动的线程,因为此线程主要是完成对UI相关事件的处理,所以也称UI线程) 对UI进行修改等操作,这是一种规则的简化,之所以这样简化是因为Android的UI操作时线程不安全的,为了避免多个线程同时操作UI造成线程安全 问题,才出现了这个简化的规则. 由此以

Android基础入门教程——3.3 Handler消息传递机制浅析

Android基础入门教程--3.3 Handler消息传递机制浅析 标签(空格分隔): Android基础入门教程 本节引言 前两节中我们对Android中的两种事件处理机制进行了学习,关于响应的事件响应就这两种:本节给大家讲解的 是Activity中UI组件中的信息传递Handler,相信很多朋友都知道,Android为了线程安全,并不允许我们在UI线程外操作UI:很多时候我们做界面刷新都需要通过Handler来通知UI组件更新!除了用Handler完成界面更新外,还可以使用runOnUiT

android线程消息传递机制——Looper,Handler,Message

android线程消息传递机制——Looper,Handler,Message 在引入这些概念之前,我们先了解一下引入这些机制的背景. 出于性能优化的考虑,Android的UI操作并不是线程安全的(如果你不懂什么是线程安全,可以阅读一下<一起探究多进程与多线程>里的数据安全与可重入),这意味着如果有多个线程同时操作某个UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件.这个UI线程也通常被我们称为主线程. 在此引

Android异步更新UI的方式之使用Handler消息传递机制

由于性能要求,android要求只能在UI线程中更新UI,要想在其他线程中更新UI,给大家介绍一种方式:使用Handler消息传递机制. 下面用这种方式更新一个TextView: package com.example.runonuithreadtest; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.widget.TextView; public

Android异步消息传递机制源码分析&amp;&amp;相关知识常被问的面试题

1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.postDelay(Runnable r, time)来在指定时间执行msg. 2).线程间通信:在执行较为耗时操作的时候,在子线程中执行耗时任务,然后handler(主线程的)把执行的结果通过sendmessage的方式发送给UI线程去执行用于更新UI. 3.handler源码分析 一.在Activ

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

一.概述 因为子线程的run()方法无法修改UI线程(主线程)的UI界面,所以Android引入了Handler消息传递机制,实现在新创建的线程中操作UI界面 二.消息类(Message) 消息类是存放在MessageQueue中的,而一个MessageQueue中可以包含多个Message对象 每一个Message对象可以通过Message.obtain()或者Handler.obtainMessage()方法获得 一个Message具有的属性: 属性 类型 介绍 arg1 int 存放整型数

断其一指------Handler消息传递机制

出于性能优化的考虑,Android的UI操作并不是线程安全的,如果多个线程同时处理UI,可能会出现线程安全的问题.所以,谷歌的大神们想出了一个简单粗暴的解决方案:只有主线程才能操作UI. 为了能够让UI线程和其他线程进行通信,引入了Handler消息传递机制. 常用方法: handleMessage() 处理消息的方法 sendEmptyMessage() 发送空消息 sendMessage() 发送消息 sendEmptyMessageDelayed 指定多少毫秒后发送空消息 sendMess

Android Handler消息机制深入浅出

作为Android开发人员,Handler这个类应该是再熟悉不过了,因为几乎任何App的开发,都会使用到Handler这个类,有些同学可能就要说了,我完全可以使用AsyncTask代替它,这个确实是可以的,但是其实AsyncTask也是通过Handler实现的,具体的大家可以去看看源码就行了,Handler的主要功能就是实现子线程和主线程的通信,例如在子线程中执行一些耗时操作,操作完成之后通知主线程跟新UI(因为Android是不允许在子线程中跟新UI的). 下面就使用一个简单的例子开始这篇文章