手机
当前位置:查字典教程网 >编程开发 >安卓软件开发 >Android后台线程和UI线程通讯实例
Android后台线程和UI线程通讯实例
摘要:本节向你展示如何在任务中发送数据给UI线程里的对象,这个特性允许你在后台线程工作,完了在UI线程展示结果。在UI线程定义一个HandlerH...

本节向你展示如何在任务中发送数据给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后台线程和UI线程通讯实例】相关文章:

Android开发之串口编程原理和实现方式

Android开发之电源管理

Android 显示和隐藏输入法实现代码

android动态壁纸调用的简单实例

深入Android Handler与线程间通信ITC的详解

Android应用程序的调试

Android Handler主线程和一般线程通信的应用分析

Android重启运用程序的代码

Android 获取进程内存使用情况方法

Android实现多线程断点下载的方法

精品推荐
分类导航