`
东天里的冬天
  • 浏览: 32731 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

Android中的Handler的机制与用法详解

阅读更多

从我们学习android开始,几乎每天都在和handler打交道.有了它,我们在子线程中处理好了耗时的操作,可以利用它来更新UI.它为我们在线程间的通信提供了很大的方便,而今天博客就来详细的介绍一下Handler的消息循环机制,一步一步的了解其中的奥妙.

1.了解概念

1.1简单实例

 

    public class DemoAct extends AppCompatActivity {  
      
        private Handler h = new Handler() {  
            @Override  
            public void handleMessage(Message msg) {  
                Toast.makeText(DemoAct.this, "收到啦", Toast.LENGTH_LONG).show();  
            }  
        };  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.act_demo);  
        }  
      
        /** 
         * 按钮的点击事件 
         * 
         * @param view 
         */  
        public void clickView(View view) {  
            new Thread(){  
                @Override  
                public void run() {  
                    h.sendEmptyMessage(0);  
                }  
            }.start();  
        }  
      
    }  

 

很多Android初学者对Android 中的Handler不是很明白,其实Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。

在下面介绍Handler机制前,首先得了解以下几个概念:

  1. Message消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
  2. Message Queue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
  3. HandlerHandler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
  4. Looper循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
  5. 线程UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。

2.什么是handler

 

  1. Handler 是 Android 给我们提供来更新 UI 的一套机制,也是一套消息处理的机制,我们可以发送消息,也可以通过它来处理消息,Handler 在我们的 framework 中是非常常见的。
  2. Android 在设计的时候,就封装了一套消息创建、传递、处理机制,如果不遵循这样的机制就没有办法更新 UI 信息,就会抛出异常信息。

 

3.如何使用handler

3.1 传递message

 

用于接受子线程发送的数据,并用此数据配合主线程更新 UI。有以下方法:

post(Ruannable);
postAtTime(Runnable, long);
postDelayed(Runnable long);

post类方法允许你排列一个 Runnable 对象到主线程队列中。

 

3.2 传递Runnable对象

 

用于通过 Handler 绑定的消息队列,安排不同操作的执行顺序,主要有以下方法:

sendEmptyMessage(int);
sendMessage(Message);
sendMessageAtTime(Message, long);
sendMessageDelayed(Message, long);

sendMessage 类方法,允许你安排一个带数据的 Message 对象到队列中,等待更新。

  1. 使用 Handler 在子线程中向 UI 线程发送一个消息进行 UI 的更新
  2. 创建一个 Message,Message msg = new Message(); msg.arg1 = 88;
  3. handler.sendMessage(msg); msg.obj = xxx;可以传递一个对象
  4. 当然不一定要用 new 一个 Message,也可以复用系统的 message 对象Message msg = handler.obtainMessage();

3.3传递callback对象

 

Callback 用于截获 handler 发送的消息,如果返回 true 就截获成功不会向下传递了。

public Handler mHandler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "HandleMessage 1", Toast.LENGTH_SHORT).show();
        return true;
    }
}) {
    public void handleMessage(Message msg) {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "handleMessage 1", Toast.LENGTH_SHORT).show();
    };
}

上面的示例中,第一个有返回值的 handlerMessage 方法是 Callback 的回调,如果返回true,则不执行下面的 handlerMessage 方法,从而达到拦截 handler 发送的消息的目的,如果返回 false,则会继续执行 handlerMessage 方法。

4.handler原理

4.1Android为何设计只能通过handler来更新UI

 

最根本的目的就是解决多线程并发的问题,假设在一个 Activity 当中,有多个线程去更新 UI,并且对更新的 UI 的操作进行枷锁处理的话又会产生什么样的问题呢? 那就是性能下降,Handler 通过消息队列,保证了消息处理的先后有序。

鉴于以上问题的考虑,Android 给我们提供了一套更新 UI 的机制,我们只要使用一套机制就好,所有的更新 UI 的操作都是在主线程中轮询处理。

4.2 handler的原理是什么

4.2.1 MessageQueue和Looper的介绍

 

在Android中,一个线程可以对应一个Looper对象,不能有多个,为什么说可以呢,Looper作为一个消息的循环器,在一个线程中可以使用它也可以不使用它,所以一个线程中可以有一个Looper对象不能有多个.
说到了消息的循环器,就必须掰扯掰扯所谓的消息队列MessageQueue.每一个Looper对象里面都会维护一个消息队列MessageQueue,它用来存放消息(Message),在MessageQueue中,存放的消息按照FIFO(先进先出)原则执行

 

 

 

  1. Handler 封装了消息的发送(主要包括消息发送给谁) Looper:
    • 内部包含一个消息队列也就是 MessageQueue,所有 Handler 发送的消息都走向这个队列。
    • Looper.loop()方法,就是一个 for 死循环,不断的从 MessageQueue 取消息,如果有消息就处理消息,没有消息就阻塞。
  2. MessageQueue,就是一个消息队列,可以添加消息,处理消息。
  3. Handler 也不难,比较简单,在构造 Handler 时候内部会跟 Looper 进行关联,通过 Looper.myLooper() 获取到 Looper,找到 Looper 也就找到了 MessageQueue。在 Handler 中发送消息,其实是向 MessageQueue 队列中发送消息。

5.handler与子线程

 

5.1自定义与线程相关的handler

 

class MyThread extends Thread {
    public Handler handler;
    @Override
    public void run() {
        Looper.prepare(); //new 一个Looper对象
        handler = new Handler() { //拿到当前线程的 Looper 对象
            @Override
            public void handlerMessage(Message msg) {
                // TODO Auto-generated method stub
                System.out.println("current thread:" + Thread.currentThread());
            }
        };
        Looper.loop();//开始死循环处理消息
    };
}


一般 UI 主线程中不要执行一些耗时的操作,这样就可以通过子线程消息来处理耗时操作。

 

 

5.2 HandlerThread是什么

 

HandlerThread 继承于 Thread,所以它本质就是个 Thread。与普通的 Thread 的差别就在于,它有个 Looper 成员变量。这个 Looper 其实就是对消息队列以及队列处理逻辑的封装,简单来说就是消息队列+消息循环。

当我们需要一个工作线程,而不是把它当作一次性消耗品,用过即废的话,就可以使用它。

private Handler mHandler = null;
private HandlerThread mHandlerThread = null;

private void sendRunnableToWorker(Ruannable run) {
    if (null == mHandlerThread) {
        mHandlerThread = new HandlerThread("WorkerThread");
        // 给工作者线程低优先级
        mHandlerThread.setPriority(Thread.MIN_PRIORITY);
        mHandlerThread.start();
    }
    if (null == mHandler) {
        mHandler = new Handler(mHandlerThread.getLooper());
    }
    mHandler.post(run);
}

 

6.主线程与子线程的信息交互

 

//创建主线程的Handler
private Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
        Message mssage = new Message();
        System.out.println("main Handler");
        //向子线程发送消息
        threadHandler.sendMessageDelayed(message, 1000);
    };
};
//创建子线程的 handler
private Handler threadHandler;

@Override
protected void onCreate(Bundle saveInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    HandlerThread thread = new HandlerThread("handlerThread");
    //创建子线程的 handler
    threadHandler = new Handler(thread.getLooper()) {
        public void handlerMessage(Message msg) {
            Message message = new Message();
            //向主线程发送消息
            mHandler.sendMessageDelayed(message, 1000);
        };
    };
}

 

7.Android中更新UI的四种方式

 

  1. runOnUiThread
  2. handler 的 post
  3. handler 的 sendMessage
  4. View 自身的 post

 

 

 

分享到:
评论

相关推荐

    android多线程handler/message机制详解

    Android 多线程Handler/Message机制详解 Android 多线程机制是 Android 应用程序中最重要的组件之一,它允许应用程序在后台执行一些操作,而不影响用户的交互体验。在 Android 中,多线程机制是基于 Handler 和 ...

    Android_Handler详解(一)

    本篇将深入探讨Handler的基本概念、使用方法以及其在多线程环境中的作用。 1. Handler是什么? Handler,中文可译为“处理器”,在Android系统中主要负责处理来自其他线程的消息。它通过发送和处理Message对象,...

    Android handler message奇怪用法详解

    在Android开发中,多线程消息处理机制是关键的一环,尤其当涉及到UI更新和后台任务同步时。本文将深入探讨一个特殊的、不常见的Handler用法,这些用法可能在日常开发中不太常见,但对理解和优化代码逻辑具有重要意义...

    Android消息机制Handler的工作过程详解

    使用场景场景 Handler在Android开发中的常见使用场景包括: 1. **子线程更新UI**:通过Handler在子线程中执行耗时操作,完成后向主线程发送消息,由主线程更新UI。 2. **定时任务**:结合`sendMessageDelayed()`...

    详解Android中Handler的内部实现原理

    总结来说,Handler机制是Android中实现多线程通信的重要手段,通过理解其内部实现原理,开发者可以更好地利用这一工具,优化应用程序的性能和用户体验。在编程实践中,深入理解Handler、Looper和MessageQueue之间的...

    详解Android Handler 机制 (一)用法全解

    ps:这是关于Android Handler 机制的第一篇文章,主要来说一下Handler的用法,本文尽量归纳完全,如有缺漏,欢迎补充。 Handler的主要作用是切换线程,以及隐式的充当接口回调的作用,当子线程网络请求结束后,通过...

    Android开发工程师面试题之handler详解。android程序员,android开发面试资料,详解

    ### Android开发工程师面试题之Handler详解 在Android开发过程中,Handler是进行线程间通信的重要机制之一,尤其在实现异步任务更新UI等场景中扮演着关键角色。本篇文章将围绕Handler的工作原理、核心组件及其实现...

    android-Handler的使用

    【Android Handler 使用详解】 Handler 是 Android 平台中用于处理线程间通信的关键组件,尤其在涉及 UI(用户界面)更新时,它扮演着至关重要的角色。在 Android 应用程序启动时,系统会默认创建一个主线程,也...

    Handler机制详解

    Handler机制是Android系统中用于线程间通信的一种关键机制,它与MessageQueue和Looper紧密协作,实现消息的传递与处理。在Android应用的主线程中,每个应用程序都有一个默认的Looper,它持续不断地从MessageQueue中...

    Android 的Handler消息传递机制.pdf

    【Android的Handler消息传递机制详解】 在Android应用开发中,多线程的使用是必不可少的,尤其是当涉及到耗时操作如网络请求、大数据处理时。然而,Android系统规定,所有与用户界面(UI)交互的操作必须在主线程...

    详解Android中Handler的使用方法

    在Android开发中,我们经常会遇到这样一种情况:在UI界面上进行某项操作后要执行一段很耗时的代码,比如我们在界面上点击了一个”下载“按钮,那么我们需要执行网络请求,这是一个耗时操作,因为不知道什么时候才能...

    Handler消息处理机制+面试说.md

    ### Handler消息处理机制详解 #### 一、原理 在Android开发中,`Handler`机制是进行线程间通信的关键技术之一。它通过一系列组件(包括`Handler`、`Looper`和`MessageQueue`)实现了一个异步消息队列,允许开发者...

    Handler与Android多线程详解

    下面是一段大家都比较熟悉的代码: 代码如下:Handler ...上述代码中的handler并没有调用线程myThread的start()方法,而是直接调用了run()方法,这也就意味着实际上并没有创建一个新的线程,只是在当前线程中调用run()

    Android面试Handler.docx

    ### Android中的Handler机制详解 #### 一、引言 在Android开发中,Handler是一个非常重要的概念,它主要用于解决主线程(UI线程)与子线程之间的消息传递问题。通过合理运用Handler,可以有效地避免UI线程被长时间...

    android线程消息机制之Handler详解

    Android线程消息机制是Android应用开发中的核心组件之一,它允许开发者在不同的线程之间进行通信,特别是子线程与主线程之间的交互。这一机制主要由Handler、Looper、Message和MessageQueue四个关键类组成。 **...

    Android 之 Looper、MessageQueue、Handler 与消息循环

    ### Android之Looper、MessageQueue、Handler与消息循环详解 #### 一、概述 在Android开发过程中,消息处理机制是至关重要的部分,它涉及到应用程序如何管理、传递和响应各种事件。本篇文章将深入探讨Android中...

    handler机制

    Handler机制是Android系统中实现线程间通信的关键技术之一。在Android应用开发过程中,经常会遇到需要在后台线程执行耗时任务,然后更新UI的情况。由于Android SDK规定了UI组件只能在创建它的线程中进行修改(通常...

Global site tag (gtag.js) - Google Analytics