Handler系列之使用

  作为一个Android开发者,我们肯定熟悉并使用过Handler机制。最常用的使用场景是“在子线程更新ui”,实际上我们知道上面的说话是错误的。因为Android中只有主线程才能更新ui,那么当我们在子线程得到更新ui通知的时候怎么办?此刻Handler存在的意义就体现出来了。我们在子线程用handler发送一个消息通知给主线程,然后让主线程更新ui,这样问题就解决了。下面让我们看看handler怎么使用的吧!!!

<一>Handler的基本使用

public class HandlerActivity extends Activity 

    private final String TAG = "HandlerActivity.class";

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.d(TAG,"arg1------"+msg.arg1); --- 1
            Log.d(TAG,"arg2------"+msg.arg2); --- 2
            Person person = (Person) msg.obj;
            if (person != null ){
                Log.d(TAG,"person.age------"+person.getAge()); --- 555
                Log.d(TAG,"person.name------"+person.getName()); --- Liu
            }
        }
    };

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

        new Thread(new Runnable() {
            @Override
            public void run() {
                /**
                 * 传递简单Integer类型消息
                 */
                Message message = new Message();
                message.arg1 = 1;
                message.arg2 = 2;

                /**
                 * 传递复杂消息
                 */
                Person person = new Person();
                person.setAge(555);
                person.setName("Liu");
                message.obj = person;

                mHandler.sendMessage(message);
            }
        }).start();
    }
}

    由上可见,我们在使用handler发送消息的时候,并且可以传递一些数据信息。在传递消息的时候我们用到了Message,并通过new的方式实例化。下面让我们看一下获取Message的第二种方法。

<二>获取Message的另一种方式以及源码分析

                Message message = mHandler.obtainMessage();
                message.sendToTarget();

同第一种方式相比,获取Message和发送Message的方法都不一样了。其实如果跟进源码你可以发现,这种方式其实就是把第一种方式封装了一下,跟随我看一下源码吧!!!

首先先来看一下获取Message的方法,入口是在Handler的obtainMessage方法:

    public final Message obtainMessage(){
        return Message.obtain(this);
    }

继续跟Message的obtain方法

   public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;
        return m;
    }

  在这里我们看到有两步操作,一个是调用本类的obtain方法,另一个是将Handler引用赋值给Message的target对象。接下来看一下obtain方法

    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

  我们看到最后实例化的方式和第一种意义,都是通过new的方法。好了!!!消息获取到了,下面看看它是怎么发送消息的吧!!!,直接看Message的sendToTarget方法。

    public void sendToTarget() {
        target.sendMessage(this);
    }

还记得我们之前给target赋值的是什么吗?没错,就是handler,所以第二种方式其实就是对第一种方式的封装。

<三>Handler的七种发信息的方法

  上面我们是通过Handler的sendMessage(Message msg)发送消息的,下面在来看看Handler的其他六种发送消息方式。这六种方法又分为两类:

    (一) 携带消息Message

      1> sendMessageAtTime(Message msg, long uptimeMillis)     在指定时间发送消息到队列

      2> sendMessageAtFrontOfQueue(Message msg)  立即发送Message到队列,而且是放在队列的最前面

      3> sendMessageDelayed(Message msg, long delayMillis)  延迟delayMillis时间发送消息到队列

    (二) 不携带消息Message

      4> sendEmptyMessage(int what)   发送空消息到队列

      5> sendEmptyMessageAtTime(int what, long uptimeMillis)  在指定时间发送空消息到队列

      6> sendEmptyMessageDelayed(int what, long delayMillis) 延迟delayMillis发送空消息到队列

时间: 2024-10-11 23:13:05

Handler系列之使用的相关文章

Handler系列之内存泄漏

本篇简单的讲一下平常使用Handler时造成内存泄漏的问题. 什么是内存泄漏?大白话讲就是分配出去的内存,回收不回来.严重会导致内存不足OOM.下面来看一下造成内存泄漏的代码: public class MemoryLeakActivity extends Activity { private MyHandler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(save

Handler系列之创建子线程Handler

上一篇我介绍了Handler机制的工作原理,默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮训和handle都是在ui线程进行的.这种情况属于子线程给主线程发消息,通知主线程更新ui...等,那么反过来,怎么才能让主线程给子线程发消息,通知子线程做一些耗时逻辑?? 之前的学习我们知道,Android的消息机制遵循三个步骤: 1 创建当前线程的Looper 2 创建当前线程的Handler 3 调用当前线

Handler系列之原理分析

上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信息,那么你们知道为什么只能通过Handler机制更新ui吗?其实最根本的目的就是解决多线程并发的问题. 假设在一个Activity中有多个线程去更新ui,并且都没有加锁,那么会是什么样子? 导致的结果就是更新界面错乱. 如果对更新ui的操作都进行加锁处理的话又产生什么问题哪? 性能下降. 处于对以上

Hook技术--Activity的启动过程的拦截

1.寻找Hook点的原则 Android中主要是依靠分析系统源码类来做到的,首先我们得找到被Hook的对象,我称之为Hook点:什么样的对象比较好Hook呢?自然是容易找到的对象.什么样的对象容易找到?静态变量和单例:在一个进程之内,静态变量和单例变量是相对不容易发生变化的,因此非常容易定位,而普通的对象则要么无法标志,要么容易改变.我们根据这个原则找到所谓的Hook点. 2.寻找Hook点 通常点击一个Button就开始Activity跳转了,这中间发生了什么,我们如何Hook,来实现Acti

【原创】源码角度分析Android的消息机制系列(六)——Handler的工作原理

ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 先看Handler的定义: /** * A Handler allows you to send and process {@link Message} and Runnable * objects associated with a thread's {@link MessageQueue}. Each Handler * instance is associated with a single thread and that thre

Handler详解系列(五)——Handler的post()方法详解

MainActivity如下: package cc.testui1; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.app.Activity; /*

Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息

MainActivity如下: package cc.c; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.widget.TextView; /** * Demo描述: * * 示例步骤如下: * 1 子线程给子线程本身发送消息 * 2 收到1的消

Handler详解系列(一)——Handler异步消息机制详解(附图)

MainActivity如下: package cc.cn; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.app.Activity; /** * Demo描述: * Android异步消息机制分析(附图) * * ===================

Netty4.0学习笔记系列之二:Handler的执行顺序(转)

http://blog.csdn.net/u013252773/article/details/21195593 Handler在netty中,无疑占据着非常重要的地位.Handler与Servlet中的filter很像,通过Handler可以完成通讯报文的解码编码.拦截指定的报文.统一对日志错误进行处理.统一对请求进行计数.控制Handler执行与否.一句话,没有它做不到的只有你想不到的. Netty中的所有handler都实现自ChannelHandler接口.按照输出输出来分,分为Chan