Android Handler原理
2020-09-17 本文已影响0人
ZZH的Android
-
Handler的使用:
(1)子线程和主线程之间相互发送消息
(2)执行延时任务 -
基本使用:
Looper.prepare();
Handler mHandler = new Handler() {
@Override public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
};
mHandler.sendEmptyMessage(0);
Looper.loop();
- 原理概述:
Looper.prepare()会创建一个Looper对象,这个Looper对象是每个线程独有的,通过ThreadLocal保存。创建Looper对象时,会创建一个MessageQueue对象用于存放消息。Handler发送的消息Message会保存在这个MessageQueue中。
创建Handler对象时,会跟Looper对象相关联,默认的是跟本线程中Looper对象关联,也可以传入其他线程中的Looper对象。
Looper.loop()会开启一个死循环用于接收Handler发送过来的消息,然后执行相应的回调函数,一般是执行Handler的handleMessage方法。
- 原理详解
Looper.prepare(), 通过ThreadLocal保存新的Looper对象。
83 public static void prepare() {
84 prepare(true);
85 }
86
87 private static void prepare(boolean quitAllowed) {
88 if (sThreadLocal.get() != null) {
89 throw new RuntimeException("Only one Looper may be created per thread");
90 }
91 sThreadLocal.set(new Looper(quitAllowed));
92 }
Looper的构造函数:创建MessageQueue对象,用于保存Handler发送的Message对象
197 private Looper(boolean quitAllowed) {
198 mQueue = new MessageQueue(quitAllowed);
199 mThread = Thread.currentThread();
200 }
Handler的构造函数,Handler有多个构造函数,主要用来初始化mLooper、mQueue、mCallBack、mAsynchronous对象。如果未传入参数,则使用当前线程的默认值。
227 public Handler(Looper looper, Callback callback, boolean async) {
228 mLooper = looper;
229 mQueue = looper.mQueue;
230 mCallback = callback;
231 mAsynchronous = async;
232 }
188 public Handler(Callback callback, boolean async) {
189 if (FIND_POTENTIAL_LEAKS) {
190 final Class<? extends Handler> klass = getClass();
191 if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
192 (klass.getModifiers() & Modifier.STATIC) == 0) {
193 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
194 klass.getCanonicalName());
195 }
196 }
197
198 mLooper = Looper.myLooper();
199 if (mLooper == null) {
200 throw new RuntimeException(
201 "Can't create handler inside thread that has not called Looper.prepare()");
202 }
203 mQueue = mLooper.mQueue;
204 mCallback = callback;
205 mAsynchronous = async;
206 }
113 public Handler() {
114 this(null, false);
115 }
116
127 public Handler(Callback callback) {
128 this(callback, false);
129 }
130
136 public Handler(Looper looper) {
137 this(looper, null, false);
138 }
139
147 public Handler(Looper looper, Callback callback) {
148 this(looper, callback, false);
149 }
150
167 public Handler(boolean async) {
168 this(null, async);
169 }
Handler发送消息:Handler通过一系列发送消息的方法将消息发送给Looper中的MessageQueue中
Handler的众多发送消息的方法最终都会走到同一个函数enqueueMessage:
638 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
639 msg.target = this; //将msg.target赋值给了当前Handler对象
640 if (mAsynchronous) {
641 msg.setAsynchronous(true);
642 }
643 return queue.enqueueMessage(msg, uptimeMillis);
644 }
这里可以看到将当前的msg对象加入了消息队列中国。并且将msg.target赋值给了当前Handler对象。
Looper.loop()方法:开启处理消息的无限循环
123 public static void loop() {
124 final Looper me = myLooper(); //返回当前线程的Looper对象,保存在ThreadLocal中
125 if (me == null) {
126 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
127 }
128 final MessageQueue queue = me.mQueue; // 拿到MessageQueue对象
129
130 // Make sure the identity of this thread is that of the local process,
131 // and keep track of what that identity token actually is.
132 Binder.clearCallingIdentity();
133 final long ident = Binder.clearCallingIdentity();
134
135 for (;;) { //处理Handler发送消息的无线循环
136 Message msg = queue.next(); // might block
137 if (msg == null) {
138 // No message indicates that the message queue is quitting.
139 return;
140 }
141
142 // This must be in a local variable, in case a UI event sets the logger
143 final Printer logging = me.mLogging;
144 if (logging != null) {
145 logging.println(">>>>> Dispatching to " + msg.target + " " +
146 msg.callback + ": " + msg.what);
147 }
148
149 final long traceTag = me.mTraceTag;
150 if (traceTag != 0) {
151 Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
152 }
153 try {
154 msg.target.dispatchMessage(msg); //这里的msg.target就是Handler
155 } finally {
156 if (traceTag != 0) {
157 Trace.traceEnd(traceTag);
158 }
159 }
160
161 if (logging != null) {
162 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
163 }
164
165 // Make sure that during the course of dispatching the
166 // identity of the thread wasn't corrupted.
167 final long newIdent = Binder.clearCallingIdentity();
168 if (ident != newIdent) {
169 Log.wtf(TAG, "Thread identity changed from 0x"
170 + Long.toHexString(ident) + " to 0x"
171 + Long.toHexString(newIdent) + " while dispatching to "
172 + msg.target.getClass().getName() + " "
173 + msg.callback + " what=" + msg.what);
174 }
175
176 msg.recycleUnchecked();
177 }
178 }
Handler的dispatchMessage函数:
93 public void dispatchMessage(Message msg) {
94 if (msg.callback != null) {
95 handleCallback(msg);
96 } else {
97 if (mCallback != null) {
98 if (mCallback.handleMessage(msg)) {
99 return;
100 }
101 }
102 handleMessage(msg);
103 }
104 }
如果有对应的callback对象,则执行相应的回调,否则执行Handler的handleMessage。