多线程与UI线程间通信

向你展示如何从任务发送数据对象上运行用户界面(UI)线程。该特性允许你的任务做背景的工作结果,然后再到UI元素如位图。

每个应用程序都有自己的特殊的线程运行的UI对象如视图对象; 这个线程称为UI线程。只有在UI线程上运行对象访问其他线程的对象。因为你的任务运行在一个线程从一个线程池不是UI线程上运行,他们没有对UI对象的访问。将数据从一个后台线程到UI线程,使用Handler的UI线程上运行。

在UI线程上定义一个Handler

Handler是Android系统的框架的一部分来管理线程。Handler对象接收消息并运行代码来处理这些消息。正常地,您为了一个新线程创建一个Handler ,但你也能创建一个Handler连接到一个现有的线程。当你连接一个Handler到你的UI线程,处理消息的代码在UI线程上运行。

例子:一个Handler对象类的构造函数中创建你的线程池, 并将对象存储在一个全局变量。它连接到UI线程通过实例化Handler(Looper)构造函数。这个构造函数使用一个Looper对象,这是另一个Android系统的线程管理框架的一部分。当你实例化一个基于特定的Looper实例的Handler对象,Handler 就像

Looper一样运行在相同的线程

代码例子:

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

里面的Handler,重写了handlerMessage()方法。Android系统调用此方法收到新消息时,线程的管理;所有的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;
            ...
        }...}
}
The next section shows how to tell the Handler to move data.

后台线程与UI线程交换数据

运行在后台的线程任务与UI线程交换数据,首先引用数据和UI对象存储在任务对象。接下来,通过任务对象和一个状态码来实例化的对象处理程序。在这个对象,包含状态和任务对象发送一个消息Handler。因为Handler是在UI线程上运行,它可以将数据移动到UI对象。.

在任务对象存储数据

例如, 这里有一个 Runnable, 运行在一个后台线程, 解码一个PhotoTask位图并将其存储在它的父对象。The 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也包含一个处理ImagVie显示位图。尽管引用同一个对象的bitmap和ImageView,, 你不能分配ImageView的位图, 因为你不是目前在UI线程上运行。

相反,下一步是把这状态发送到PhotoTask对象。

发送状态的对象层次结构

PhotoTask 在层次结构中是下一个更高的对象。它维护引用的解码数据和视图对象将显示数据。它从PhotoDecodeRunnable接收状态代码,并将它传递到维护线程池和实例化的对象处理程序:

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

从PhotoTask对象,PhotoManager对象接收状态代码和PhotoTask对象的句柄。因为状态TASK_COMPLETE,创建一个消息包含状态和任务对象并将它发送到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()检查每个传入消息的状态码。如果TASK_COMPLETE状态代码,然后,任务完成后,PhotoTask对象在消息中包含一个位图和一个ImageView。因为Handler.handleMessage()在UI线程上运行,它可以安全地移动ImageView位图:

private PhotoManager() {
        ...
            mHandler = new Handler(Looper.getMainLooper()) {
                @Override
                public void handleMessage(Message inputMessage) {
                    // Gets the task from the incoming Message object.
                    PhotoTask photoTask = (PhotoTask) inputMessage.obj;
                    // Gets the ImageView for this task
                    PhotoView localView = photoTask.getPhotoView();
                    ...
                    switch (inputMessage.what) {
                        ...
                        // The decoding is done
                        case TASK_COMPLETE:
                            /*
                             * Moves the Bitmap from the task
                             * to the View
                             */
                            localView.setImageBitmap(photoTask.getImage());
                            break;
                        ...
                        default:
                            /*
                             * Pass along other messages from the UI
                             */
                            super.handleMessage(inputMessage);
                    }
                    ...
                }
                ...
            }
            ...
    }
...
}

Hander的更多相关文章

  1. android学习日记25--ANR和Hander消息机制

    1.ANR(Application Not Responding)定义 在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:A ...

  2. Handler 、 Looper 、Message异步消息处理线程机制( hander消息机制原理)

    Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念. 那么什么叫异步消息处理线程呢? 异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次, ...

  3. Android Handler机制 (一个Thead中可以建立多个Hander,通过msg.target保证MessageQueue中的每个msg交由发送message的handler进行处理 ,但是 每个线程中最多只有一个Looper,肯定也就一个MessageQuque)

    转载自http://blog.csdn.net/stonecao/article/details/6417364 在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长 ...

  4. android hander

    http://www.cnblogs.com/plokmju/p/android_Handler.html 前言 Android的消息传递机制是另外一种形式的“事件处理”,这种机制主要是为了解决And ...

  5. hander消息机制原理

    基本原理 线程中调用Handler.sendMsg()方法(参数是Message对象),将需要Main线程处理的事件 添加到Main线程的MessageQueue中,Main线程通过MainLoope ...

  6. 通过Hander进行界面刷新

    Timer timer; TimerTask task; Handler handler;//先声明这3个变量 //在onCreate方法内 handler = new Handler(){ @Ove ...

  7. android hander 线程用法

    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanc ...

  8. Looper、Hander、HandlerThread

    一.Message .Looper.Handler之间的关系 1.系统发送的Message消息传送给Handler,Handler将Message放入自己的looper队列的底部   然后再从Loop ...

  9. hander消息机制原理(looper轮询监听机制)

    基本原理 线程中调用Handler.sendMsg()方法(参数是Message对象),将需要Main线程处理的事件 添加到Main线程的MessageQueue中,Main线程通过MainLoope ...

随机推荐

  1. [转载]C#中各种计时器

    1.使用 Stopwatch 类 (System.Diagnostics.Stopwatch) Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 S ...

  2. [转载]再次谈谈easyui datagrid 的数据加载

    这篇文章只谈jQuery easyui datagrid 的数据加载,因为这也是大家谈论最多的内容.其实easyui datagrid加载数据只有两种方式:一种是ajax加载目标url返回的json数 ...

  3. API HOOK

    API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...

  4. spoj 227

    留着 #include <cstdio> #include <cstring> #include <cstdlib> #define lson l, m, rt & ...

  5. spoj 368

    额   最小生成树 ........ #include <cstdio> #include <cstring> #include <algorithm> using ...

  6. Samza在YARN上的启动过程 =》 之一

    运行脚本,提交job 往YARN提交Samza job要使用run-job.sh这个脚本. samza-example/target/bin/run-job.sh  --config-factory= ...

  7. 如果Java 失宠于Oracle,那么未来会怎么样?

    [编者按]对于前不久 Oracle 裁掉了一部分 Java 布道师,近日一位 Oracle 前高管称其为该机构对Java的「计划报废」.如果这个计划是属实的,那么对于寻常的开发者.已经采用了 Java ...

  8. linux 文件比对总结

    1. 过滤a.log的重复数据 #统计 cat datatest.log|sort|uniq -d |wc -l #放入b.log cat datatest.log|sort|uniq -d > ...

  9. [itint5]完全二叉树节点个数的统计

    http://www.itint5.com/oj/#4 这题是利用完全二叉树的性质计算节点数目.那么是通过比较左右子树的最左结点的高度来看那边是满的,然后递归计算. //使用getLeftChildN ...

  10. IIS会话过期的问题/WCF日志管理

    http://technet.microsoft.com/zh-cn/library/cc725624(v=ws.10).aspx http://msdn.microsoft.com/zh-cn/li ...