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

 更新时间:2014年06月26日 09:05:36   作者:冰冻鱼  
这篇文章主要介绍了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.

相关文章

  • Android图片三级缓存开发

    Android图片三级缓存开发

    这篇文章主要为大家详细介绍了Android图片三级缓存开发的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Android图片处理工具类BitmapUtils

    Android图片处理工具类BitmapUtils

    这篇文章主要为大家详细介绍了Android图片的处理工具类BitmapUtils,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Android编程实现通话录音功能的方法

    Android编程实现通话录音功能的方法

    这篇文章主要介绍了Android编程实现通话录音功能的方法,结合实例形式较为详细的分析了Android广播接收机制实现录音功能的操作技巧,需要的朋友可以参考下
    2017-06-06
  • Android通过多点触控的方式对图片进行缩放的实例代码

    Android通过多点触控的方式对图片进行缩放的实例代码

    这篇文章主要介绍了Android通过多点触控的方式对图片进行缩放的实例代码,完成了点击图片就能浏览大图的功能,并且在浏览大图的时候还可以通过多点触控的方式对图片进行缩放。
    2018-05-05
  • Android studio git创建与删除标签(Tag)的教程详解

    Android studio git创建与删除标签(Tag)的教程详解

    这篇文章主要介绍了Android studio git创建与删除标签(Tag)的教程详解,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Android 6.0动态权限申请教程

    Android 6.0动态权限申请教程

    本文主要介绍了Android 6.0动态权限申请的教程,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • Android仿网易云音乐播放界面

    Android仿网易云音乐播放界面

    这篇文章主要为大家详细介绍了Android仿网易云音乐播放界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Android类FileDownloadList分析

    Android类FileDownloadList分析

    这篇文章主要介绍了Android类FileDownloadList分析,需要的朋友可以参考下
    2014-07-07
  • Android悬浮窗的实现步骤

    Android悬浮窗的实现步骤

    最近想做一个悬浮窗秒表的功能,所以看下悬浮窗具体的实现步骤,接下来通过本文给大家介绍Android悬浮窗的实现,需要的朋友可以参考下
    2024-01-01
  • java  深入理解内存映射文件原理

    java 深入理解内存映射文件原理

    这篇文章主要介绍了java 深入理解内存映射文件原理的相关资料,虚拟内存与内存映射文件的区别与联系,内存映射文件的原理和效率,需要的朋友可以参考下
    2016-11-11

最新评论