Android异步通信:手把手教你使用Handler消息传递机制(含实例讲解)

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类 & 创建了子类

代码语言:javascript复制/**

* 方式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()代码语言:javascript复制// 步骤1:在主线程中创建Handler实例

private Handler mhandler = new mHandler();

// 步骤2:在工作线程中 发送消息到消息队列中 & 指定操作UI内容

// 需传入1个Runnable对象

mHandler.post(new Runnable() {

@Override

public void run() {

... // 需执行的UI操作

}

});

// 步骤3:开启工作线程(同时启动了Handler)

// 多线程可采用AsyncTask、继承Thread类、实现Runnable5. 实例讲解本文将用实例逐个讲解 Handler的用法

注:

由于Handler的作用 = 将工作线程需操作UI的消息 传递 到主线程,使得主线程可根据工作线程的需求 更新UI,从而避免线程操作不安全的问题故下文的实例 = 1个简单 “更新UI操作” 的案例主布局文件相同 = 1个用于展示的TextView,具体如下:布局代码:activity_main.xml

代码语言:javascript复制

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">

android:id="@+id/show"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="" />

实例的源码地址:Carson_Ho的Github:Handler

(建议:先fork下来再看,效果会更好哦!)

5.1 使用 Handler.sendMessage()方式1:新建Handler子类(内部类)具体使用代码语言:javascript复制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:匿名内部类具体使用代码语言:javascript复制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()具体使用代码语言:javascript复制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内存泄露的原因