热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android后台线程和UI线程通讯实例

这篇文章主要介绍了Android后台线程和UI线程通讯实例,每一步的要点和步骤都有提及,并配有代码例子,需要的朋友可以参考下

本节向你展示如何在任务中发送数据给UI线程里的对象,这个特性允许你在后台线程工作,完了在UI线程展示结果。

在UI线程定义一个Handler

Handler是Android系统线程管理框架里的一部分。一个Handler对象接收消息,并且运行代码来处理消息。正常情况下,你为新线程创建Handler,但你也可以为已有的线程创建一个Handler.当你连接Handler到UI线程时,处理消息的代码会在UI线程上运行.

在创建线程池的类的构造器里实例化Handler对象,保存在全局变量里。用Handler(Looper)方法实例化,连接到UI线程,构造方法使用Looper对象,也是Android系统线程管理框架里的一部分.Looper类有一个静态方法getMainLooper()可以获取UI线程的Looper对象。如:

代码如下:

private PhotoManager() {
...
    // Defines a Handler object that's attached to the UI thread
    mHandler = new Handler(Looper.getMainLooper()) {
    ...

在Handler里,覆盖handleMessage()。Android系统会在Handler管理的线程收到新消息时,调用该方法。一个指定线程的所有Handler对象都会收到相同的消息。

代码如下:

        /*
         * handleMessage() defines the operations to perform when
         * the Handler receives a new Message to process.
         */
        @Override
        public void handleMessage(Message inputMessage) {
            // Gets the image task from the incoming Message object.
            PhotoTask photoTask = (PhotoTask) inputMessage.obj;
            ...
        }
    ...
    }
}

从任务里移动数据到UI线程

要从后台线程的任务里移动数据到UI线程的对象,先保存引用到数据和任务对象的UI对象里,接下来把任务对象和状态码传给Handler对象。在这个对象里,发送一个包含状态 和任务对象的消息给Handler.因为Handler在UI线程上运行,它可以移动数据给UI对象。

在任务对象里存储数据

如,这是一个Runnable,运行在后台线程,它解析Bitmap,并保存到它的父对象。Runnable同时保存状态码DECODE_STATE_COMPLETED。

代码如下:

// A class that decodes photo files into Bitmaps
class PhotoDecodeRunnable implements Runnable {
    ...
    PhotoDecodeRunnable(PhotoTask downloadTask) {
        mPhotoTask = downloadTask;
    }
    ...
    // Gets the downloaded byte array
    byte[] imageBuffer = mPhotoTask.getByteBuffer();
    ...
    // Runs the code for this task
    public void run() {
        ...
        // Tries to decode the image buffer
        returnBitmap = BitmapFactory.decodeByteArray(
                imageBuffer,
                0,
                imageBuffer.length,
                bitmapOptions
        );
        ...
        // Sets the ImageView Bitmap
        mPhotoTask.setImage(returnBitmap);
        // Reports a status of "completed"
        mPhotoTask.handleDecodeState(DECODE_STATE_COMPLETED);
        ...
    }
    ...
}
...

PhotoTask还包含一个ImageView引用,用来显示Bitmap.尽管引用Bitmap和ImageView是在同一个对象里,但因为不是在UI线程,你不能直接让ImageView显示Bitmap.

沿对象层次逐级发送状态

PhotoTask持有解码的数据和显示数据的View对象的引用,它从PhotoDecodeRunnable接收到状态码,并且沿着线程池里引用的对象和Handler实例传送。

代码如下:

public class PhotoTask {
    ...
    // Gets a handle to the object that creates the thread pools
    sPhotoManager = PhotoManager.getInstance();
    ...
    public void handleDecodeState(int state) {
        int outState;
        // Converts the decode state to the overall state.
        switch(state) {
            case PhotoDecodeRunnable.DECODE_STATE_COMPLETED:
                outState = PhotoManager.TASK_COMPLETE;
                break;
            ...
        }
        ...
        // Calls the generalized state method
        handleState(outState);
    }
    ...
    // Passes the state to PhotoManager
    void handleState(int state) {
        /*
         * Passes a handle to this task and the
         * current state to the class that created
         * the thread pools
         */
        sPhotoManager.handleState(this, state);
    }
    ...
}

移动数据到UI

PhotoManager从PhotoTask对象接收到状态码和PhotoTask对象的句柄。因为状态是TASK_COMPLETE,创建一个包含状态和任务对象的Message,发送给Handler。

代码如下:

public class PhotoManager {
    ...
    // Handle status messages from tasks
    public void handleState(PhotoTask photoTask, int state) {
        switch (state) {
            ...
            // The task finished downloading and decoding the image
            case TASK_COMPLETE:
                /*
                 * Creates a message for the Handler
                 * with the state and the task object
                 */
                Message completeMessage =
                        mHandler.obtainMessage(state, photoTask);
                completeMessage.sendToTarget();
                break;
            ...
        }
        ...
    }

最终,Handler.handleMessage()为每个进来的Message检查状态码。如果状态码是TASK_COMPLETE,任务就是完成了,Message里的PhotoTask对象包含Bitmap和ImageView.因为Handler.handleMessage()运行在UI线程,它可以安全地为ImageView设置Bitmap.


推荐阅读
  • 地球坐标、火星坐标及百度坐标间的转换算法 C# 实现
    本文介绍了WGS84坐标系统及其精度改进历程,探讨了火星坐标系统的安全性和应用背景,并详细解析了火星坐标与百度坐标之间的转换算法,提供了C#语言的实现代码。 ... [详细]
  • 2015款Chromebook Pixel评测:高端Chrome OS笔记本体验
    在笔记本电脑领域,Chromebook Pixel凭借其精致的铝合金外壳、细腻的显示屏和舒适的键盘,成为了外观设计的佼佼者。然而,尽管外观出众,它是否值得购买仍需考量。 ... [详细]
  • 探讨了在使用客户端JavaScript时,确保其完整性和来源可靠性的方法,特别是在安全性要求较高的应用中。 ... [详细]
  • ServletContext接口在Java Web开发中扮演着重要角色,它提供了一种方式来获取关于整个Web应用程序的信息。通过ServletContext,开发者可以访问初始化参数、共享数据以及应用资源。 ... [详细]
  • 并发环境下的集合元素移除技巧与注意事项
    探讨在并发编程中对集合进行元素移除操作时应注意的关键点,包括使用迭代器的安全方法以及避免常见错误。 ... [详细]
  • 医院患者监护系统设计与实施
    本文探讨了某医院计划开发的一个基于计算机的患者监护系统。该系统旨在实时收集患者的生理数据(如脉搏、体温、血压和心电图),并自动记录患者状况,生成日志。当监测到的数据超出预设的安全范围时,系统将自动向护士发送警报。此外,系统还支持按需打印特定患者的病情报告。 ... [详细]
  • 百度云加速节点IP白名单配置指南:宝塔面板Nginx防火墙应用
    百度云加速为已备案的网站提供免费加速服务,但使用宝塔面板自带Nginx防火墙的用户需将百度云加速的CDN IP段加入白名单以确保正常访问。本文将详细介绍如何操作。 ... [详细]
  • Flowable 6.6.0 表单引擎在Web应用中的集成与使用
    本文档提供了Flowable 6.6.0版本中表单引擎在Web应用程序中的配置和使用指南,包括表单引擎的初始化、配置以及在Web环境下的具体实现方法。 ... [详细]
  • 当您的笔记本电脑出现无法正常关机的情况时,可以通过多种方法进行排查和修复,包括检查声音文件、减少启动程序、调整电源管理设置等。 ... [详细]
  • 本文探讨了在渗透测试中信息收集阶段使用的几种端口扫描技术,包括nmap、masscan、socket、telnet及nc等工具的应用与比较。 ... [详细]
  • 近期,谷歌公司的一名安全工程师Eduardo Vela在jQuery Mobile框架中发现了一项可能引发跨站脚本攻击(XSS)的安全漏洞。此漏洞使得使用jQuery Mobile的所有网站面临潜在的安全威胁。 ... [详细]
  • addcslashes—以C语言风格使用反斜线转义字符串中的字符addslashes—使用反斜线引用字符串bin2hex—函数把包含数据的二进制字符串转换为十六进制值chop—rt ... [详细]
  • 本文整理了一系列Java面试问题,涵盖Java开发环境的分类、Java语言的核心特性、Linux环境下Java SE的安装步骤、常用的Java开发工具介绍,以及类与对象的基本概念等。 ... [详细]
  • 探讨GET与POST请求数据传输的最大容量
    在Web开发领域,GET和POST是最常见的两种数据传输方法。本文将深入探讨这两种请求方式在不同环境下的数据传输能力及其限制。 ... [详细]
  • 尽管PHP是一种强大且灵活的Web开发语言,但开发者在使用过程中常会陷入一些典型的陷阱。本文旨在列出PHP开发中最为常见的10种错误,并提供相应的预防建议。 ... [详细]
author-avatar
心窝子难受呢
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有