Java简单模拟Android中Handler-Message机制

在Android中主线程与子线程的通信十分重要,Google工程师为我们提供了Handler-Message机制来解决他们之间的交互问题。今天,我们就来简单理解Handler-Message机制的原理,在Java中简单模拟该机制。代码示例Github地址HandlerDemo

首先,看一下简单流程图(不太专业)

由上图可知,流程中主要相关类有Handler、Message、MessageQueue、Looper;下面,我们就围绕它们来简单分析该流程图:

1.我们一般在主线程创建Handler,接着开启子线程完成指定任务,再将任务数据封装Message,交由Handler发出;

2.接着,MessageQueue接收Handler发来的Message,将其根据Message中的属性when(时刻值)进行排序,重组队列;
(在这插一段MessageQueue的由来:MessageQueue的创建其实是跟随着Looper的创建,而Looper的一个特性就是一个线程只允许有一个Looper,缓存在ThreadLocal<Looper>中,而Looper的创建Looper.prepare()是要在创建Handler之前调用的,这 样就保证了一个MessageQueue所缓存的队列消息均是需要分发到该Looper所在线程的。)

3.接下来,通过Looper.loop()取出MessageQueue中的消息,而Looper.loop()以及MessageQueue中的next()均是堵塞线程的,所以和永动机一般,可以不停地取出消息;

4.最后,Looper.loop()取出的Message通过Message中的target(Handler)实现消息分发,而dispatchMessage(Message)方法为Handler中的方法,这样就实现了“谁发出的消息谁处理”,所以一个线程中的多个Handler可以实现相对独立的工作。

接下来,看一下示例代码及其运行效果

代码示例:

package com.wkp.test;

import android.wkp.Handler;
import android.wkp.Looper;
import android.wkp.Message;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class Main {

    public static void main(String[] args) {
        //主线程Looper准备
        Looper.prepareMainLooper();
        //创建Handler
        final MainHandler handler = new MainHandler();
        //开启线程池
        Executor executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int position = i + 1;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000 * position);
                        //子线程传任务到主线程
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                System.out.println(Thread.currentThread().getName() + " : " + position);
                            }
                        },1000);

                        Thread thread = Thread.currentThread();
                        //子线程传消息到主线程
                        Message.obtain(handler,position,position,position,"主线程,你好!我是线程:"+thread.getName()).sendToTarget();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        //消息队列循环
        Looper.loop();
    }

    /**
     * 主线程处理子线程传回的消息
     */
    private static class MainHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WhatConstants.WHAT_ONE:
                    String obj1 = (String) msg.obj;
                    System.out.println(obj1);
                    break;
                case WhatConstants.WHAT_TWO:
                    String obj2 = (String) msg.obj;
                    System.out.println(obj2);
                    break;
                case WhatConstants.WHAT_THREE:
                    String obj3 = (String) msg.obj;
                    System.out.println(obj3);
                    break;
                case WhatConstants.WHAT_FOUR:
                    String obj4 = (String) msg.obj;
                    System.out.println(obj4);
                    break;
                case WhatConstants.WHAT_FIVE:
                    String obj5 = (String) msg.obj;
                    System.out.println(obj5);
                    break;
                case WhatConstants.WHAT_SIX:
                    String obj6 = (String) msg.obj;
                    System.out.println(obj6);
                    break;
                case WhatConstants.WHAT_SEVEN:
                    String obj7 = (String) msg.obj;
                    System.out.println(obj7);
                    break;
                case WhatConstants.WHAT_EIGHT:
                    String obj8 = (String) msg.obj;
                    System.out.println(obj8);
                    break;
                case WhatConstants.WHAT_NINE:
                    String obj9 = (String) msg.obj;
                    System.out.println(obj9);
                    break;
                case WhatConstants.WHAT_TEN:
                    String obj10 = (String) msg.obj;
                    System.out.println(obj10);
                    break;
            }
        }
    }
}

运行效果:

主线程,你好!我是线程:pool-1-thread-1
main : 1
主线程,你好!我是线程:pool-1-thread-2
main : 2
主线程,你好!我是线程:pool-1-thread-3
main : 3
主线程,你好!我是线程:pool-1-thread-4
主线程,你好!我是线程:pool-1-thread-5
main : 4
main : 5
主线程,你好!我是线程:pool-1-thread-6
主线程,你好!我是线程:pool-1-thread-7
main : 6
main : 7
主线程,你好!我是线程:pool-1-thread-8
main : 8
主线程,你好!我是线程:pool-1-thread-9
主线程,你好!我是线程:pool-1-thread-10
main : 9
main : 10

最后,欢迎亲友们留言交流

如果大家想更深入的了解,可以观看源码Github地址,源码中有详尽的注释。大家如果有更好的意见或建议以及好的灵感,请邮箱作者,谢谢!

QQ邮箱:[email protected]

163邮箱:[email protected]

Gmail邮箱:[email protected]

原文地址:http://blog.51cto.com/13583739/2069365

时间: 2024-11-02 14:29:10

Java简单模拟Android中Handler-Message机制的相关文章

深入解析Android中Handler消息机制

Android提供了Handler 和 Looper 来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(MessageExchange).Handler消息机制可以说是Android系统中最重要部分之一,所以,本篇博客我们就来深入解析Android中Handler消息机制. Handler的简单使用 为什么系统不允许子线程更新UI 因为的UI控件不是线程安全的. 如果在多线程中并发访问可能会导致UI控件处于不可预期的状态,那为什么不对UI控件的访

异步消息处理机制-Android中Handler原理(续)

异步消息处理线程是指线程启动后会进入一个无限循环,每循环一次,从内部的消息队列里面取出一个消息,并回调相应的消息处理函数.一般在任务常驻,比如用户交互任务的情况下使用异步消息处理线程. 之前在Android中Handler原理里面研究过android里实现异步消息处理线程的方式,基本逻辑如图所示 今天就用java将其简单的模拟出来加深印象,下面的类图是用工具导出的,不太正规,不过能大概看出类之间的关系 Message类:消息类 public class Message { public int

android中的多线程机制

Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制.学习Android的消息处理机制,有几个概念(类)必须了解: 1.       Message 消息,理解为线程间通讯的数据单元.例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程. 2.       Message Queue 消息队列,用来存放通过Handler发布的消息,按照先进先出执行. 3.       Handler Handler是Messa

Android中对Handle机制的理解

一.重要參考资料 [參考资料] 眼下来看,以下的几个网址中的内容质量比較不错.基本不须要再读别的网址了. 1.android消息机制一 http://xtfncel.javaeye.com/blog/663517 Android消息机制(一) 一.    角色描写叙述 1.Looper: 一个线程能够产生一个Looper对象.由它来管理此线程里的Message Queue(消息队列). 2.Handler: 你能够构造Handler对象来与Looper沟通.以便push新消息到Message Q

Android中Alarm的机制

本次给大家分析的是Android中Alarm的机制所用源码为最新的Android4.4.4.首先简单介绍如何使用Alarm并给出其工作原理,接着分析Alarm和Timer以及Handler在完成定时任务上的差别,最后分析Alarm机制的源码. 什么是Alarm Alarm是android提供的用于完成闹钟式定时任务的类,系统通过AlarmManager来管理所有的Alarm,Alarm支持一次性定时任务和循环定时任务,它的使用方式很简单,这里不多做介绍,只给出一个简单的示例: [java] vi

Android中Handler的使用方法——在子线程中更新界面

本文主要介绍Android的Handler的使用方法.Handler可以发送Messsage和Runnable对象到与其相关联的线程的消息队列.每个Handler对象与创建它的线程相关联,并且每个Handler对象只能与一个线程相关联. Handler一般有两种用途:1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器.2)线程间通信.在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息.当你创建子线程时,你可以再你的子线程中拿到父线程中创建的Han

Android中的消息机制

在分析Android消息机制之前.我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListener { private TextView stateText; private Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); s

详细讲解Android中的Message的源码

相信大家对于Android中的Handler是在为熟悉不过了,但是要知道,Handler就其本身而言只是一个壳子,真正在内部起到作用的是Message这个类,对于Message这个类,相信大家也不会陌生,正如大家经常用到的Message.obtain()的方法一样.但是大家又是否知道obtain()方法里面为我们做了哪些操作了,下面我就带领大家进行Message的王国,去一探究竟吧. 首先映入眼帘的是这样的一行代码: ? 1 public final class Message implemen

浅析Android中的消息机制(转)

原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: 1 public class MainActivity extends Activity implements View.OnClickListener { 2 private TextView stateText; 3 private Button btn; 4 5 @Override 6 public void onC