Android source code(7.1) message-Handler 机制
2017-04-07 11:15
239 查看
Message handler处理原理:
1、handler-msg 用Looper维护了一个消息队列,采用for死循环对这个队列进行遍历,当有新的msg消息被压入deque时,将会被及时的处理。
2、Main Thread在创建的时候会为当前thread主动分配一个looper,而子线程需要手动创建looper
从code的角度分析一下 message-handler机制是如何运作的
首先,我们来看一下Looper.java里面的主要code
1、ThreadLocal sThreadLocal :本地线程变量,ThreadLocal的特点是在不同的thread中保存的值相互独立,所以,它为不同的thread保存thread自己的looper对象,请注意prepare和prepareMainLooper这两个方法
2、mQueue:保存message的消息队列
3、在loop()方法里,msg.target中的target指向的是Handler对象,所以 msg.target.dispatchMessage(msg); 会调用到Handler.dispatchMessage方法
1、Handler里面的mQueue 是Looper里面的mQueue的引用
2、当sendMsg的时候最终是调用enqueueMessage方法将msg进行入队列操作
很多时候,我们会使用HandlerThread来进行Handler-msg操作
1、HandlerThread是thread
2、HandlerThread在run方法里面为我们构造好了Looper对象已经它的消息队列
下面我们看一下主线程是如何为handler分配一个looper的,下面给出了部分code:
app process启动的时候会调用ActivityThread.main方法,这里会为app分配一个全局的Looper对象
本章介绍结束!
1、handler-msg 用Looper维护了一个消息队列,采用for死循环对这个队列进行遍历,当有新的msg消息被压入deque时,将会被及时的处理。
2、Main Thread在创建的时候会为当前thread主动分配一个looper,而子线程需要手动创建looper
从code的角度分析一下 message-handler机制是如何运作的
首先,我们来看一下Looper.java里面的主要code
public final class Looper { static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static Looper sMainLooper; // guarded by Looper.class final MessageQueue mQueue; final Thread mThread; private Printer mLogging; private long mTraceTag; public static void prepare() { prepare(true); } 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)); } public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } public static Looper getMainLooper() { synchronized (Looper.class) { return sMainLooper; } } 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; Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block if (msg == null) { return; } try { msg.target.dispatchMessage(msg); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } final long newIdent = Binder.clearCallingIdentity(); msg.recycleUnchecked(); } } public static @Nullable Looper myLooper() { return sThreadLocal.get(); } public static @NonNull MessageQueue myQueue() { return myLooper().mQueue; } private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); } public boolean isCurrentThread() { return Thread.currentThread() == mThread; } public void quit() { mQueue.quit(false); } public void quitSafely() { mQueue.quit(true); } public @NonNull Thread getThread() { return mThread; } public @NonNull MessageQueue getQueue() { return mQueue; } }
1、ThreadLocal sThreadLocal :本地线程变量,ThreadLocal的特点是在不同的thread中保存的值相互独立,所以,它为不同的thread保存thread自己的looper对象,请注意prepare和prepareMainLooper这两个方法
2、mQueue:保存message的消息队列
3、在loop()方法里,msg.target中的target指向的是Handler对象,所以 msg.target.dispatchMessage(msg); 会调用到Handler.dispatchMessage方法
public class Handler { private static final boolean FIND_POTENTIAL_LEAKS = false; private static final String TAG = "Handler"; final Looper mLooper; final MessageQueue mQueue; final Callback mCallback; final boolean mAsynchronous; IMessenger mMessenger; /** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } private static void handleCallback(Message message) { message.callback.run(); } public interface Callback { public boolean handleMessage(Message msg); } public void handleMessage(Message msg) { } public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } public Handler() { this(null, false); } public Handler(Callback callback) { this(callback, false); } public Handler(Looper looper) { this(looper, null, false); } public Handler(Looper looper, Callback callback) { this(looper, callback, false); } /** * @hide */ public Handler(boolean async) { this(null, async); } /** * @hide */ 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; } public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0); } public final boolean sendEmptyMessage(int what) { return sendEmptyMessageDelayed(what, 0); } public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); } public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageAtTime(msg, uptimeMillis); } public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); } public final boolean sendMessageAtFrontOfQueue(Message msg) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, 0); } private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
1、Handler里面的mQueue 是Looper里面的mQueue的引用
2、当sendMsg的时候最终是调用enqueueMessage方法将msg进行入队列操作
很多时候,我们会使用HandlerThread来进行Handler-msg操作
public class HandlerThread extends Thread { int mPriority; int mTid = -1; Looper mLooper; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } public HandlerThread(String name, int priority) { super(name); mPriority = priority; } protected void onLooperPrepared() { } @Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; } public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; } public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } public int getThreadId() { return mTid; } }
1、HandlerThread是thread
2、HandlerThread在run方法里面为我们构造好了Looper对象已经它的消息队列
下面我们看一下主线程是如何为handler分配一个looper的,下面给出了部分code:
ActivityThread.java public static void main(String[] args) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); // Make sure TrustedCertificateStore looks in the right place for CA certificates final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
app process启动的时候会调用ActivityThread.main方法,这里会为app分配一个全局的Looper对象
本章介绍结束!
相关文章推荐
- Android消息处理机制:Handler Thread Message Looper
- Android的消息处理机制(图+源码分析)——Looper,Handler,Message
- (转)Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- (转)android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- Android消息处理机制:Handler Thread Message Looper []
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- [转] android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android消息处理机制:Handler Thread Message Looper
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- Android Handler Message 通信机制
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理惩罚机制(图+源码解析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message