Android异步通信:手把手教你使用Handler消息传递机制(含实例讲解)
Posted Carson带你学Android
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android异步通信:手把手教你使用Handler消息传递机制(含实例讲解)相关的知识,希望对你有一定的参考价值。
前言
- 在
android
开发的多线程应用场景中,Handler
机制十分常用 - 今天,我将献上一份
Handler
机制的使用教程 ,希望你们会喜欢
Anroid Handler系列文章教程
Android异步通信:Handler机制学习攻略
Android异步通信:Handler使用教程
Android异步通信:Handler工作原理
Android异步通信:Handler机制源码
Android异步通信:详解Handler内存泄露的原因
目录
1. Handler 机制简介
-
定义
一套Android
消息传递机制 / 异步通信机制 -
作用
在多线程的应用场景中,将工作线程中需更新UI
的操作信息 传递到 UI
主线程,从而实现 工作线程对UI
的更新处理,最终实现异步消息的处理
- 为什么要用
Handler
消息传递机制
答:多个线程并发更新UI的同时 保证线程安全。具体描述如下
- 总结
使用Handler
的原因:将工作线程需操作UI
的消息 传递 到主线程,使得主线程可根据工作线程的需求 更新UI
,从而避免线程操作不安全的问题
2. 相关概念
关于 Handler
机制中的相关概念如下:
在下面的讲解中,我将直接使用英文名讲解,即
Handler
、Message
、Message Queue
、Looper
,希望大家先熟悉相关概念
3. 使用方式
Handler
使用方式 因发送消息到消息队列的方式不同而不同- 共分为2种:使用
Handler.sendMessage()
、使用Handler.post()
4. 使用步骤
方式1:使用 Handler.sendMessage()
在该使用方式中,又分为2种:新建Handler
子类(内部类)、匿名 Handler
子类
但本质相同,即 继承了
Handler
类 & 创建了子类
/**
* 方式1:新建Handler子类(内部类)
*/
// 步骤1:自定义Handler子类(继承Handler类) & 复写handleMessage()方法
class mHandler extends Handler
// 通过复写handlerMessage() 从而确定更新UI的操作
@Override
public void handleMessage(Message msg)
...// 需执行的UI操作
// 步骤2:在主线程中创建Handler实例
private Handler mhandler = new mHandler();
// 步骤3:创建所需的消息对象
Message msg = Message.obtain(); // 实例化消息对象
msg.what = 1; // 消息标识
msg.obj = "AA"; // 消息内容存放
// 步骤4:在工作线程中 通过Handler发送消息到消息队列中
// 可通过sendMessage() / post()
// 多线程可采用AsyncTask、继承Thread类、实现Runnable
mHandler.sendMessage(msg);
// 步骤5:开启工作线程(同时启动了Handler)
// 多线程可采用AsyncTask、继承Thread类、实现Runnable
/**
* 方式2:匿名内部类
*/
// 步骤1:在主线程中 通过匿名内部类 创建Handler类对象
private Handler mhandler = new Handler()
// 通过复写handlerMessage()从而确定更新UI的操作
@Override
public void handleMessage(Message msg)
...// 需执行的UI操作
;
// 步骤2:创建消息对象
Message msg = Message.obtain(); // 实例化消息对象
msg.what = 1; // 消息标识
msg.obj = "AA"; // 消息内容存放
// 步骤3:在工作线程中 通过Handler发送消息到消息队列中
// 多线程可采用AsyncTask、继承Thread类、实现Runnable
mHandler.sendMessage(msg);
// 步骤4:开启工作线程(同时启动了Handler)
// 多线程可采用AsyncTask、继承Thread类、实现Runnable
方式2:使用Handler.post()
// 步骤1:在主线程中创建Handler实例
private Handler mhandler = new mHandler();
// 步骤2:在工作线程中 发送消息到消息队列中 & 指定操作UI内容
// 需传入1个Runnable对象
mHandler.post(new Runnable()
@Override
public void run()
... // 需执行的UI操作
);
// 步骤3:开启工作线程(同时启动了Handler)
// 多线程可采用AsyncTask、继承Thread类、实现Runnable
5. 实例讲解
本文将用实例逐个讲解 Handler
的用法
注:
- 由于
Handler
的作用 = 将工作线程需操作UI的消息 传递 到主线程,使得主线程可根据工作线程的需求 更新UI,从而避免线程操作不安全的问题- 故下文的实例 = 1个简单 “更新
UI
操作” 的案例- 主布局文件相同 = 1个用于展示的
TextView
,具体如下:
布局代码:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context="com.example.carson_ho.handler_learning.MainActivity">
<TextView
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
</RelativeLayout>
实例的源码地址:Carson_Ho的Github:Handler
(建议:先fork
下来再看,效果会更好哦!)
5.1 使用 Handler.sendMessage()
方式1:新建Handler子类(内部类)
- 具体使用
public class MainActivity extends AppCompatActivity
public TextView mTextView;
public Handler mHandler;
// 步骤1:(自定义)新创建Handler子类(继承Handler类) & 复写handleMessage()方法
class Mhandler extends Handler
// 通过复写handlerMessage() 从而确定更新UI的操作
@Override
public void handleMessage(Message msg)
// 根据不同线程发送过来的消息,执行不同的UI操作
// 根据 Message对象的what属性 标识不同的消息
switch (msg.what)
case 1:
mTextView.setText("执行了线程1的UI操作");
break;
case 2:
mTextView.setText("执行了线程2的UI操作");
break;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.show);
// 步骤2:在主线程中创建Handler实例
mHandler = new Mhandler();
// 采用继承Thread类实现多线程演示
new Thread()
@Override
public void run()
try
Thread.sleep(3000);
catch (InterruptedException e)
e.printStackTrace();
// 步骤3:创建所需的消息对象
Message msg = Message.obtain();
msg.what = 1; // 消息标识
msg.obj = "A"; // 消息内存存放
// 步骤4:在工作线程中 通过Handler发送消息到消息队列中
mHandler.sendMessage(msg);
.start();
// 步骤5:开启工作线程(同时启动了Handler)
// 此处用2个工作线程展示
new Thread()
@Override
public void run()
try
Thread.sleep(6000);
catch (InterruptedException e)
e.printStackTrace();
// 通过sendMessage()发送
// a. 定义要发送的消息
Message msg = Message.obtain();
msg.what = 2; //消息的标识
msg.obj = "B"; // 消息的存放
// b. 通过Handler发送消息到其绑定的消息队列
mHandler.sendMessage(msg);
.start();
- 运行结果
方式2:匿名内部类
- 具体使用
public class MainActivity extends AppCompatActivity
public TextView mTextView;
public Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.show);
// 步骤1:在主线程中 通过匿名内部类 创建Handler类对象
mHandler = new Handler()
// 通过复写handlerMessage()从而确定更新UI的操作
@Override
public void handleMessage(Message msg)
// 根据不同线程发送过来的消息,执行不同的UI操作
switch (msg.what)
case 1:
mTextView.setText("执行了线程1的UI操作");
break;
case 2:
mTextView.setText("执行了线程2的UI操作");
break;
;
// 采用继承Thread类实现多线程演示
new Thread()
@Override
public void run()
try
Thread.sleep(3000);
catch (InterruptedException e)
e.printStackTrace();
// 步骤3:创建所需的消息对象
Message msg = Message.obtain();
msg.what = 1; // 消息标识
msg.obj = "A"; // 消息内存存放
// 步骤4:在工作线程中 通过Handler发送消息到消息队列中
mHandler.sendMessage(msg);
.start();
// 步骤5:开启工作线程(同时启动了Handler)
// 此处用2个工作线程展示
new Thread()
@Override
public void run()
try
Thread.sleep(6000);
catch (InterruptedException e)
e.printStackTrace();
// 通过sendMessage()发送
// a. 定义要发送的消息
Message msg = Message.obtain();
msg.what = 2; //消息的标识
msg.obj = "B"; // 消息的存放
// b. 通过Handler发送消息到其绑定的消息队列
mHandler.sendMessage(msg);
.start();
- 运行结果
5.2 使用 Handler.post()
- 具体使用
public class MainActivity extends AppCompatActivity
public TextView mTextView;
public Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.show);
// 步骤1:在主线程中创建Handler实例
mHandler = new Handler();
// 步骤2:在工作线程中 发送消息到消息队列中 & 指定操作UI内容
new Thread()
@Override
public void run()
try
Thread.sleep(3000);
catch (InterruptedException e)
e.printStackTrace();
// 通过psot()发送,需传入1个Runnable对象
mHandler.post(new Runnable()
@Override
public void run()
// 指定操作UI内容
mTextView.setText("执行了线程1的UI操作");
);
.start();
// 步骤3:开启工作线程(同时启动了Handler)
// 此处用2个工作线程展示
new Thread()
@Override
public void run()
try
Thread.sleep(6000);
catch (InterruptedException e)
e.printStackTrace();
mHandler.post(new Runnable()
@Override
public void run()
mTextView.setText("执行了线程2的UI操作");
);
.start();
- 运行结果
至此,关于Handler
的异步消息传递机制的使用讲解完毕。
6. 总结
- 本文对
Handler
异步通信传递机制的使用进行了全面讲解 - Anroid Handler系列文章教程
Android异步通信:Handler机制学习攻略
Android异步通信:Handler使用教程
Android异步通信:Handler工作原理
Android异步通信:Handler源码分析
Android异步通信:详解Handler内存泄露的原因
欢迎关注Carson_Ho的CSDN博客 与 公众号!
博客链接:https://carsonho.blog.csdn.net/
请点赞!因为你的鼓励是我写作的最大动力!
以上是关于Android异步通信:手把手教你使用Handler消息传递机制(含实例讲解)的主要内容,如果未能解决你的问题,请参考以下文章
Android:手把手教你 实现Activity 与 Fragment 相互通信(含Demo)
asyncawait让异步编程更简单,全方位讲解,手把手教你能不会?