Android 中的Handler详解
来源:互联网 发布:大数据对零售业的影响 编辑:程序博客网 时间:2024/06/06 05:02
Android 中的Handler详解
先看一下一个线程中使用Handler的步骤
class MyThread extends Thread { @Override public void run() { Looper.prepare(); MyHandler handler = new MyHandler(); /** * do something */ Looper.loop();//loop()要在最后调用 } }
首先,我们要先调用Looper.prepare()方法,在这个方法中
会调用 prepare(boolean quitAllowed) 方法,在这个方法中我们能看到一行代码 sThreadLocal.set(new Looper(quitAllowed));,这个代码的意思就是 new一个Looper 放在当前线程的 ThreadLocal.Values 中,具体ThreadLocal.Values是什么东西,我们以后会解释,现在只需要理解为线程的一个成员变量,每个线程存储的都不一样我们需要 new 一个自定义的Handler (继承自android.os.Handler,实现了handleMessage(Message msg)方法) ,下面就看一下自定义的MyHandler
在这一步,我们就可以实现自己的逻辑,需要在这个线程中执行什么就写什么,没什么好说的
在我们的第四步,也是最最关键的一步,调用 Looper.loop(); 方法,首先说明这个方法是会阻塞的,也许会有人问,那阻塞之后岂不是线程就停在这了?确实是这样,所以会在最后一步调用这个方法,这个方法的作用就是要轮询 MessageQueue ,如果有新消息就交给 Handler 处理,下面就是 Looper.loop() 方法
/** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycleUnchecked(); }}
从上面的代码中我们看到有这么一行代码 Message msg = queue.next(); // might block 源码中已经加了注释,说明这个方法可能会阻塞;感兴趣的可以找到 MessageQueue.next() 方法,看看里面代码的作用,我在这里直接告诉大家,这个方法是从MessageQueue中取消息,如果MessageQueue中没有消息,这段代码就会阻塞,取到消息之后我们看到有这么一行代码 msg.target.dispatchMessage(msg); msg.target 是 Handler,我们看一下 Handler.dispatchMessage(msg) 方法
这个就很好理解了,如果Message有callback,那么就执行Message的callback方法,mCallback是Handler的一个内部类,Handler有一个构造函数
需要的同学可以研究一下,这里不做过多解释
主要看一下 handleMessage(Message msg) 方法,这个方法是要在MyHandler中自己重写的,重写之后就能从别的线程中切换当前线程来执行代码
那么Handler如何将Message放在MessageQueue中呢
比如我们调用 Handler.sendMessage(Message msg) 方法,我们看一下源码
源码中调用了 sendMessageDelayed(Message msg, long delayMillis) 方法
这个函数中又调用了 sendMessageAtTime(Message msg, long uptimeMillis) 方法
好了,重磅炸弹来了,我们可以看到一行代码 return enqueueMessage(queue, msg, uptimeMillis); 看一下 enqueueMessage() 方法
终于我们找到了 MessageQueue.enqueueMessage(Message msg, long when) 方法,这是 MessageQueue 中方法,感兴趣的同学可以看一下这段代码,我就不贴上来了,这段代码的主要意思就是将一个新消息放在 MessageQueue 上,这样我们在上面调用 Looper.loop() 就能取到这个消息
至此,所有的你需要知道的Handler就这么多
下一节我们会讲解ThreadLocal
最后加上流程图,画的不好,请见谅
- Android 中的Handler详解
- android中的handler机制详解
- Android中的Handler的post方法详解
- 详解Android中的Looper,Handler和Message
- Android中的Handler的post方法详解
- Android中的Handler的post方法详解
- Android中的Handler的post方法详解
- Android中的Handler的post方法详解
- Android中的Handler的post方法详解
- Android中的Handler详解以及和Thread的区别
- Android中的Handler详解以及和Thread的区别
- Android中的Handler详解以及和Thread的区别
- Android中的Handler的机制与用法详解
- Android中的Handler的机制与用法详解
- Android中的Handler的机制与用法详解
- Android中的Handler的机制与用法详解
- Android中的Handler的机制与用法详解
- Android中的Handler的机制与用法详解
- 利用css写出二级导航
- android编译报错
- 六轴系统中陀螺仪输出的角速度的一些问题
- C# 在Word文档中生成条形码
- 网页中导航栏实现子菜单下拉效果
- Android 中的Handler详解
- RedHat系统下安装CentOS系统的yum
- Android SDK各个版本API的特性及兼容性
- servlet客户端http请求及响应及httpservletrequest,httpservletresponse详解
- Oracle11.2新特性之INSERT提示IGNORE_ROW_ON_DUPKEY_INDEX
- Linux关机与重启命令
- 曾想亲手解析未知化合物晶体结构
- C#中DataTable中的Compute方法使用收集(续)
- 利用xampp搭建Yii1.1.17