Android Handler介绍

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)
    }
}

匿名 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)
        
    }
}

(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)
    }
}

Handler就介绍到这里。

特大号外!!!

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值