我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android Handler的作用与用法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android Handler的作用与用法

1.什么是handler?

Handler是Android SDK来处理异步消息的核心类。
子线程与主线程通过Handler来进行通信。子线程可以通过Handler来通知主线程进行UI更新。

Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制。每个Hanlder都关联了一个线程,每个线程内部都维护了一个消息队列MessageQueue,这样Handler实际上也就关联了一个消息队列。可以通过Handler将Message和Runnable对象发送到该Handler所关联线程的MessageQueue(消息队列)中,然后该消息队列一直在循环拿出一个Message,对其进行处理,处理完之后拿出下一个Message,继续进行处理,周而复始。当创建一个Handler的时候,该Handler就绑定了当前创建Hanlder的线程。从这时起,该Hanlder就可以发送Message和Runnable对象到该Handler对应的消息队列中,当从MessageQueue取出某个Message时,会让Handler对其进行处理。

Handler可以用来在多线程间进行通信,在另一个线程中去更新UI线程中的UI控件只是Handler使用中的一种典型案例,除此之外,Handler可以做很多其他的事情。每个Handler都绑定了一个线程,假设存在两个线程ThreadA和ThreadB,并且HandlerA绑定了 ThreadA,在ThreadB中的代码执行到某处时,出于某些原因,我们需要让ThreadA执行某些代码,此时我们就可以使用Handler,我们可以在ThreadB中向HandlerA中加入某些信息以告知ThreadA中该做某些处理了。由此可以看出,Handler是Thread的代言人,是多线程之间通信的桥梁,通过Handler,我们可以在一个线程中控制另一个线程去做某事。
 

2.什么是MessageQueue和Looper

如图MessageQueue用来保存子线程从Handler所发送未处理的消息,Looper依次取出MessageQueue中的消息传递给主线程Hanlder响应处理。

3.为什么使用handler,MessageQueue,Looper?

主线程无法进行时间比较繁长的任务,所以需要子线程进行处理,然而子线程无法进行UI的界面更新,所以我们需要使用handler来传递消息给主线程,让其完成UI的更新。由于主线程和子线程进行不同的时间工作,所要需要用MessageQueue来存放子线程的消息,Looper取出消息交给主线程响应。

4.使用handler的主要步骤

Handler提供了两种方式解决我们在本文一开始遇到的问题(在一个新线程中更新主线程中的UI控件),一种是通过post方法,一种是调用sendMessage方法。

a. 使用post方法,代码如下:

package ispring.com.testhandler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements Button.OnClickListener {
    private TextView statusTextView = null;
    //uiHandler在主线程中创建,所以自动绑定主线程
    private Handler uiHandler = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        statusTextView = (TextView)findViewById(R.id.statusTextView);
        Button btnDownload = (Button)findViewById(R.id.btnDownload);
        btnDownload.setOnClickListener(this);
        System.out.println("Main thread id " + Thread.currentThread().getId());
    }
    @Override
    public void onClick(View v) {
        DownloadThread downloadThread = new DownloadThread();
        downloadThread.start();
    }
    class DownloadThread extends Thread{
        @Override
        public void run() {
            try{
                System.out.println("DownloadThread id " + Thread.currentThread().getId());
                System.out.println("开始下载文件");
                //此处让线程DownloadThread休眠5秒中,模拟文件的耗时过程
                Thread.sleep(5000);
                System.out.println("文件下载完成");
                //文件下载完成后更新UI
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Runnable thread id " + Thread.currentThread().getId());
                        MainActivity.this.statusTextView.setText("文件下载完成");
                    }
                };
                uiHandler.post(runnable);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

 我们在Activity中创建了一个Handler成员变量uiHandler,Handler有个特点,在执行new Handler()的时候,默认情况下Handler会绑定当前代码执行的线程,我们在主线程中实例化了uiHandler,所以uiHandler就自动绑定了主线程,即UI线程。当我们在DownloadThread中执行完耗时代码后,我们将一个Runnable对象通过post方法传入到了Handler中,Handler会在合适的时候让主线程执行Runnable中的代码,这样Runnable就在主线程中执行了,从而正确更新了主线程中的UI
b. 使用sendMessage方法,代码如下:

package ispring.com.testhandler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements Button.OnClickListener {
    private TextView statusTextView = null;
    //uiHandler在主线程中创建,所以自动绑定主线程
    private Handler uiHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    System.out.println("handleMessage thread id " + Thread.currentThread().getId());
                    System.out.println("msg.arg1:" + msg.arg1);
                    System.out.println("msg.arg2:" + msg.arg2);
                    MainActivity.this.statusTextView.setText("文件下载完成");
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        statusTextView = (TextView)findViewById(R.id.statusTextView);
        Button btnDownload = (Button)findViewById(R.id.btnDownload);
        btnDownload.setOnClickListener(this);
        System.out.println("Main thread id " + Thread.currentThread().getId());
    }
    @Override
    public void onClick(View v) {
        DownloadThread downloadThread = new DownloadThread();
        downloadThread.start();
    }
    class DownloadThread extends Thread{
        @Override
        public void run() {
            try{
                System.out.println("DownloadThread id " + Thread.currentThread().getId());
                System.out.println("开始下载文件");
                //此处让线程DownloadThread休眠5秒中,模拟文件的耗时过程
                Thread.sleep(5000);
                System.out.println("文件下载完成");
                //文件下载完成后更新UI
                Message msg = new Message();
                //虽然Message的构造函数式public的,我们也可以通过以下两种方式通过循环对象获取Message
                //msg = Message.obtain(uiHandler);
                //msg = uiHandler.obtainMessage();
                //what是我们自定义的一个Message的识别码,以便于在Handler的handleMessage方法中根据what识别
                //出不同的Message,以便我们做出不同的处理操作
                msg.what = 1;
                //我们可以通过arg1和arg2给Message传入简单的数据
                msg.arg1 = 123;
                msg.arg2 = 321;
                //我们也可以通过给obj赋值Object类型传递向Message传入任意数据
                //msg.obj = null;
                //我们还可以通过setData方法和getData方法向Message中写入和读取Bundle类型的数据
                //msg.setData(null);
                //Bundle data = msg.getData();
                //将该Message发送给对应的Handler
                uiHandler.sendMessage(msg);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

通过Message与Handler进行通信的步骤是:
1. 重写Handler的handleMessage方法,根据Message的what值进行不同的处理操作
2. 创建Message对象
虽然Message的构造函数式public的,我们还可以通过Message.obtain()或Handler.obtainMessage()来获得一个Message对象(Handler.obtainMessage()内部其实调用了Message.obtain())。
3. 设置Message的what值
Message.what是我们自定义的一个Message的识别码,以便于在Handler的handleMessage方法中根据what识别出不同的Message,以便我们做出不同的处理操作。
4. 设置Message的所携带的数据,简单数据可以通过两个int类型的field arg1和arg2来赋值,并可以在handleMessage中读取。
5. 如果Message需要携带复杂的数据,那么可以设置Message的obj字段,obj是Object类型,可以赋予任意类型的数据。或者可以通过调用Message的setData方法赋值Bundle类型的数据,可以通过getData方法获取该Bundle数据。
6. 我们通过Handler.sendMessage(Message)方法将Message传入Handler中让其在handleMessage中对其进行处理。
需要说明的是,如果在handleMessage中 不需要判断Message类型,那么就无须设置Message的what值;而且让Message携带数据也不是必须的,只有在需要的时候才需要让其携带数据;如果确实需要让Message携带数据,应该尽量使用arg1或arg2或两者,能用arg1和arg2解决的话就不要用obj,因为用arg1和arg2更高效。
 


作者:wu311894565


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android Handler的作用与用法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android Handler的作用与用法

1.什么是handler? Handler是Android SDK来处理异步消息的核心类。 子线程与主线程通过Handler来进行通信。子线程可以通过Handler来通知主线程进行UI更新。 Handler是Android中引入的一种让开发
2022-06-06

Android中AsyncTask与handler用法实例分析

本文实例讲述了Android中AsyncTask与handler用法。分享给大家供大家参考,具体如下: 首先,我们得明确下一个概念,什么是UI线程。顾名思义,ui线程就是管理着用户界面的那个线程! android的ui线程操作并不是安全的,
2022-06-06

Android中Handler有什么作用

这篇文章主要讲解了“Android中Handler有什么作用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android中Handler有什么作用”吧!在性能优化方面考虑,Android的U
2023-06-04

Android中Handler与Message如何使用

这期内容当中小编将会给大家带来有关Android中Handler与Message如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Message:Message是在线程之间传递的消息,它可以在内部携带
2023-05-30

详解Android中Handler的使用方法

在Android开发中,我们经常会遇到这样一种情况:在UI界面上进行某项操作后要执行一段很耗时的代码,比如我们在界面上点击了一个”下载“按钮,那么我们需要执行网络请求,这是一个耗时操作,因为不知道什么时候才能完成。为了保证不影响UI线程,所
2022-06-06

Android中的Handler与多线程应用实例

本文首先解释一下handler是用来干嘛的,然后通过例子介绍其在多线程中的应用。 什么是Handler handler通俗一点讲就是用来在各个进程之间发送数据的处理对象。在任何进程中,只要获得了另一个进程的handler则可以通过handl
2022-06-06

android开发教程之android的handler使用方法

Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title.首先我们看一下习惯了Java编程的人,在不知道Handler的用法之前是怎么样写的程序,代码如下所示:代码如下:pack
2022-06-06

android Handler详细使用方法实例

开发环境为android4.1.Handler使用例1这个例子是最简单的介绍handler使用的,是将handler绑定到它所建立的线程中.本次实验完成的功能是:单击Start按钮,程序会开始启动线程,并且线程程序完成后延时1s会继续启动该
2022-06-06

Android Loop机制中Looper与handler怎么使用

今天小编给大家分享一下Android Loop机制中Looper与handler怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了
2023-07-04

详解Android Handler 机制 (一)用法全解

ps:这是关于Android Handler 机制的第一篇文章,主要来说一下Handler的用法,本文尽量归纳完全,如有缺漏,欢迎补充。 Handler的主要作用是切换线程,以及隐式的充当接口回调的作用,当子线程网络请求结束后,通过hand
2022-06-06

Android消息机制Handler用法有哪些

这篇文章主要讲解了“Android消息机制Handler用法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android消息机制Handler用法有哪些”吧!1.简述Handler消息
2023-06-21

Android 中Handler有什么用

Android 中Handler有什么用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Android Handler的详解Handler我们常常用于通知主线程做
2023-05-30

Android中handler使用浅析

1. Handler使用引出 现在作为客户,有这样一个需求,当打开Activity界面时,开始倒计时,倒计时结束后跳转新的界面(思维活跃的朋友可能立马想到如果打开后自动倒计时,就类似于各个APP的欢迎闪屏页面),如下图:作为初学者,可能觉得
2022-06-06

Android编程开发之seekBar采用handler消息处理操作的方法

本文实例讲述了Android编程开发之seekBar采用handler消息处理操作的方法。分享给大家供大家参考,具体如下: 该案例简单实现进度条可走,可拖拽的功能,下面请看源码: 布局文件:
2022-06-06

Ray-Handler的ToReadHandler有什么作用

本篇内容主要讲解“Ray-Handler的ToReadHandler有什么作用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Ray-Handler的ToReadHandler有什么作用”吧!Ra
2023-06-19

python中handler的作用是什么

这篇文章给大家介绍python中handler的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。python可以做什么Python是一种编程语言,内置了许多有效的工具,Python几乎无所不能,该语言通俗易懂、
2023-06-14

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录