Android Handler介绍

举报
yd_221104950 发表于 2020/12/05 01:21:17 2020/12/05
【摘要】 Handler的用途 Handler是子线程(工作线程)与主线程之间的通信桥梁。由于更新UI只能在主线程里完成,所以在子线程里的工作完成后,可以通过Handler来通知主线程更新UI组件。 什么是主线程呢? 当app应用程序启动时创建的第1个线程就是主线程(MainThread)又叫UI线程,因为它专门用于UI的操作。 什么是子线程呢? 子线程,又因其作用而被...

Handler的用途

Handler是子线程(工作线程)与主线程之间的通信桥梁。由于更新UI只能在主线程里完成,所以在子线程里的工作完成后,可以通过Handler来通知主线程更新UI组件。

什么是主线程呢?

当app应用程序启动时创建的第1个线程就是主线程(MainThread)又叫UI线程,因为它专门用于UI的操作。

什么是子线程呢?

子线程,又因其作用而被称为工作线程,是程序员手动创建的,常用于一些耗时的操作,如网络请求、数据加载等。

使用Handler的好处

在实际开发中,常常存在多个线程并发操作UI组件的情况,那么线程安全显得尤为重要。如果想做到既可以多线程并发操作UI,又保证线程安全的话,Handler将会是一个不错的选择。
Handler是异步消息机制模型。

Handler的工作流程

阶段 说明
1.异步通信准备 (1)在主线程启动时会自动创建Looper消息循环处理器,Looper创建时会同时创建MessageQueue消息队列,创建Looper、MessageQueue完成后,Looper消息循环理器就会自动进入消息循环;(2)在主线程里手动创建Handler处理器对象,此时Handler对象会自动绑定主线程里的Looper、MessageQueue对象。
2.消息发送 工作线程通过Handler处理器对象发送消息Message到MessageQueue消息队列
3.消息循环 Looper循环器取出MessageQueue中的消息,然后把消息分发给该消息的Handler处理器。
4.消息处理 (1)Handler处理器接收Looper循环器发来的消息;(2)根据消息Message的内容进行UI操作

相关的术语的介绍:

  • Message:消息对象,用于存储需要操作的通信信息,是Handler对象接收和处理的对象。
  • MessageQueue:消息队列,是一个有先进先出特点的数据结构。用于存储Handler对象发送过来的Message消息对象。
  • Handler:是工作线程与主线程通信的媒介。它可以向消息队列MessageQueue添加消息Message,也可以接收并处理Looper循环器分发过来的Message消息。

如图所示:
在这里插入图片描述

号外!号外!号外!

线程(Thread)、循环器(Looper)、处理者(Handler)之间的关系有如下限制:

  • 一个线程Thread只能绑定一个循环器Looper
  • 一个循环器Looper可以绑定多个处理器Handler,但是一个处理器Handler只能绑定一个循环器Looper。

Handler的一般使用方法

有sendMessage、post两种方式。
(1)使用 Handler.sendMessage()
此种方式分为Handler子类(内部类)匿名 Handler子类两种。

Handler子类(内部类):

package com.ti.controlsound;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity { /** * 方式1:Handler子类(内部类) * 1、自定义Handler子类(继承Handler类) * 2、重写handleMessage()方法 */ // 第一步:新建Handler子类(内部类) class MyHandler extends Handler { @Override public void handleMessage(Message msg) { // TODO 需执行的UI操作 Log.d("MESSAGE",(String) msg.obj); } } // 第二步:在主线程中创建Handler实例 private Handler mHandler = new MyHandler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { // 第三步:创建所需的消息对象 Message msg = Message.obtain(); // 实例化消息对象 msg.what = 1; // 消息标识 msg.obj = "Hello World"; // 消息内容存放 // 第四步:在工作线程中,通过Handler发送消息到消息队列中 mHandler.sendMessage(msg); } }).start();// 第五步:开启工作线程(同时启动了Handler) }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

匿名 Handler子类:

package com.ti.controlsound;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity { /** * 方式2:匿名内部类 */ // 第一步:在主线程中通过匿名内部类创建Handler类对象 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO 需执行的UI操作 Log.d("MESSAGE",(String) msg.obj); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { // 第二步:创建所需的消息对象 Message msg = Message.obtain(); // 实例化消息对象 msg.what = 1; // 消息标识 msg.obj = "Hello World"; // 消息内容存放 // 第三步:在工作线程中,通过Handler发送消息到消息队列中 mHandler.sendMessage(msg); } }).start();// 第四步:开启工作线程(同时启动了Handler) }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

(2)使用Handler.post()

package com.ti.controlsound;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity { // 第一步:在主线程中创建Handler类对象 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO 需执行的UI操作 Log.d("MESSAGE", (String) msg.obj); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { // 第二步:在工作线程中 发送消息到消息队列中和指定操作UI内容 // 需传入1个Runnable对象 mHandler.post(new Runnable() { @Override public void run() { // 需执行的UI操作  } }); } }).start();// 第三步:开启工作线程(同时启动了Handler) }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

Handler就介绍到这里。

特大号外!!!

上面使用Handler的方式都有可能引发内存溢出,相关解决方法,请查看《Android性能优化之Handler内存溢出》。谢谢

文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_40763897/article/details/96144921

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。