Handler机制源码探索(一):UI线程中Handler的初始化流程
来源:互联网 发布:wmware 怎么安装mac os 编辑:程序博客网 时间:2024/05/29 13:02
最近用到Handler,感觉很神奇,不过一直仅仅只停留在会使用的地步,这段时间抽出一点时间来看看源码。
我们都知道,Handler的使用无法离开几个类,Looper、Message以及MessageQueue。
其中Message类不用多说,是用来传递各类参数或消息所用的类,当handler.sendMessage() 或者 msg.sendToTarget() 时,被发送的Message对象则会进入到MessageQueue中。Looper则作为MessageQueue的管理类,不断的从MessageQueue中取出Message,并让对应的handler去处理调用handleMessage(Message msg)。让我们来看一下源码在这里是怎么实现的。
我们就以Handler在Activity中的初始化的开始吧。
package com.example.devin.test;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity { private TextView mTextView = null; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { mTextView.setText(msg.obj.toString()); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.hello); new Thread() { @Override public void run() { Message msg = mHandler.obtainMessage(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } msg.obj = "Hi I'm from thread."; mHandler.sendMessage(msg); } }.start(); }}
public Handler() { this(null, false); }最终调用构造器为:
public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }我们可以看到,当实例化Handler时,会调用
mLooper = Looper.myLooper();
我们再来看下myLooper()方法:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper> /*...Others...*/ //sThreadLocal声明及初始化 public static @Nullable Looper myLooper() { return sThreadLocal.get(); }我们知道ThreadLocal可以用来在线程数据内共享某些数据。当无法取到时,则会返回null。但是如果myLooper()方法返回null,按理来说我们的demo也应该抛出异常“Can't create handler inside thread that has not called Looper.prepare()”,可是为啥没报错呢?
原来是这样,在Activity初始化时,会在ActivityThread中的main方法中,调用Looper.prepareMainLooper(),会为UI线程创建一个Looper并保存到sThreadLocal属性中,自然不会出现此问题。所以说,在UI线程中,会自动创建一个Looper,就是在这个时候创建的。在Demo中当new Handler时,与Handler相关联的即是通过Looper.prepareMainLooper()返回回来的Looper。
public static void prepareMainLooper() { prepare(false);//在此处调用prepare方法,创建Looper。 synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } /*.....Others......*/ //prepare方法 private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed));//实例化Looper并set至sThreadLocal中。 }
我们再来看下Looper的构造器:
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed);//初始化MessageQueue mThread = Thread.currentThread(); }
我们可以发现,Looper初始化的时候,初始化了MessageQueue,同时也与当前的线程进行关联。
而当初始化Handler时,也就是将Looper与Handler进行关联,也同时将Looper中的MessageQueue进行关联。
以上,就是Handler在UI线程中的初始化流程。
如有任何错漏,欢迎各位大神指教,小生在此谢过!~
- Handler机制源码探索(一):UI线程中Handler的初始化流程
- 关于UI线程与非UI线程交互,有关Handler机制等(一)
- Handler消息机制源码解析(一)
- Handler 机制(一)
- Handler机制更新UI线程控件
- Android中子线程和UI线程之间通信的方式(Handler与Thread-附源码)
- 探索Handler机制原理
- Handler机制流程梳理、源码分析
- 【源码解读】Handler消息机制流程分析
- Android中Handler源码解析(一)
- handler源码探索
- Handler详解(一)---关联到UI线程
- handler机制的源码分析
- Android异步机制一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步机制一:使用Thread+Handler实现非UI线程更新UI界面
- 在Android子线程中初始化handler后,为什么该子线程也能更新UI?
- Android线程间消息机制-Handler源码分析(FrameWork)
- Handler机制的处理(一)
- C++ STL中Map的按Key排序和按Value排序
- 运算符重载
- menu
- 练字一定要用钢笔吗?
- RxJava 与 Retrofit 结合的最佳实践
- Handler机制源码探索(一):UI线程中Handler的初始化流程
- 用 LaTeX 写漂亮学位论文(from wloo)
- 阅读程序Stl
- 101. Symmetric Tree
- 怎么练字才会有效果,多久才能有体现
- mysql数据类型
- TOEFL writing——causative verbs
- Guass_seidel迭代法
- andriod 注解找控件 简单步骤