主要是想到了 之前的问题,android 2.2时候 的系统和现在的系统,2.2之前即使直接在子线程更新也是可以的,现在除了个别的控件其他的都要放在主线程里面更新。就分析一下
ProgressBar是可以在自线程更新 就以ProgressBar为例
ProgressBar设置进度的方法
public synchronized void setProgress(
int progress) {
setProgress(progress , false) ;
}
setProgress(progress , false) ;
}
没什么特别的接着看
synchronized void setProgress(
int progress
, boolean fromUser) {
if (mIndeterminate) {
return;
}
if (progress < 0) {
progress = 0 ;
}
if (progress > mMax) {
progress = mMax ;
}
if (progress != mProgress) {
mProgress = progress ;
refreshProgress(R.id.progress , mProgress , fromUser) ;
}
}
if (mIndeterminate) {
return;
}
if (progress < 0) {
progress = 0 ;
}
if (progress > mMax) {
progress = mMax ;
}
if (progress != mProgress) {
mProgress = progress ;
refreshProgress(R.id.progress , mProgress , fromUser) ;
}
}
private synchronized void
refreshProgress(
int id
, int progress
, boolean fromUser) {
if (mUiThreadId == Thread.currentThread().getId()) {
doRefreshProgress(id , progress , fromUser , true) ;
} else {
if (mRefreshProgressRunnable == null) {
mRefreshProgressRunnable = new RefreshProgressRunnable() ;
}
final RefreshData rd = RefreshData.obtain(id , progress , fromUser) ;
mRefreshData.add(rd) ;
if (mAttached && !mRefreshIsPosted) {
post(mRefreshProgressRunnable) ;
mRefreshIsPosted = true;
}
}
}
if (mUiThreadId == Thread.currentThread().getId()) {
doRefreshProgress(id , progress , fromUser , true) ;
} else {
if (mRefreshProgressRunnable == null) {
mRefreshProgressRunnable = new RefreshProgressRunnable() ;
}
final RefreshData rd = RefreshData.obtain(id , progress , fromUser) ;
mRefreshData.add(rd) ;
if (mAttached && !mRefreshIsPosted) {
post(mRefreshProgressRunnable) ;
mRefreshIsPosted = true;
}
}
}
在这个方法中 refreshProgress 中 进行了 ui线程判断, 如果是ui线程就 去刷新了 进度 下面的 mRefreshProgressRunnable 其实是继承了 runnable 的一个刷新的线程 然后如果不是主线程就
去post 看一下post方法 在ProgressBar的父类 View中
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo ;
if (attachInfo != null) {
return attachInfo.mHandler.post(action) ;
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action) ;
return true;
}
final AttachInfo attachInfo = mAttachInfo ;
if (attachInfo != null) {
return attachInfo.mHandler.post(action) ;
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action) ;
return true;
}
AttachInfo也是通过handler来更新的ui 如果他不存在 在看一下下面的方法
static RunQueue getRunQueue() {
RunQueue rq = sRunQueues.get() ;
if (rq != null) {
return rq ;
}
rq = new RunQueue() ;
sRunQueues.set(rq) ;
return rq ;
}
RunQueue rq = sRunQueues.get() ;
if (rq != null) {
return rq ;
}
rq = new RunQueue() ;
sRunQueues.set(rq) ;
return rq ;
}
这个对象 将想要被执行的任务 runnable 保存在 handlerAction 里面 看下面
//这个方法在 调用 performTraversals 时会被执行
static final class RunQueue {
private final ArrayList<HandlerAction> mActions = new ArrayList<HandlerAction>() ;
void post(Runnable action) {
postDelayed(action , 0) ;
}
void postDelayed(Runnable action , long delayMillis) {
//这个很简单 只是把要执行的信息放在 HandlerAction 类里面 把要执行的runnable保存
HandlerAction handlerAction = new HandlerAction() ;
handlerAction.action = action ;
handlerAction.delay = delayMillis ;
synchronized (mActions) {
mActions.add(handlerAction) ;
}
}
void removeCallbacks(Runnable action) {
final HandlerAction handlerAction = new HandlerAction() ;
handlerAction.action = action ;
synchronized (mActions) {
final ArrayList<HandlerAction> actions = mActions ;
while (actions.remove(handlerAction)) {
// Keep going
}
}
}
//还是用handler 去执行 runnbale 任务
void executeActions(Handler handler) {
synchronized (mActions) {
final ArrayList<HandlerAction> actions = mActions ;
final int count = actions.size() ;
for ( int i = 0 ; i < count ; i++) {
final HandlerAction handlerAction = actions.get(i) ;
handler.postDelayed(handlerAction.action , handlerAction.delay) ;
}
actions.clear() ;
}
}
static final class RunQueue {
private final ArrayList<HandlerAction> mActions = new ArrayList<HandlerAction>() ;
void post(Runnable action) {
postDelayed(action , 0) ;
}
void postDelayed(Runnable action , long delayMillis) {
//这个很简单 只是把要执行的信息放在 HandlerAction 类里面 把要执行的runnable保存
HandlerAction handlerAction = new HandlerAction() ;
handlerAction.action = action ;
handlerAction.delay = delayMillis ;
synchronized (mActions) {
mActions.add(handlerAction) ;
}
}
void removeCallbacks(Runnable action) {
final HandlerAction handlerAction = new HandlerAction() ;
handlerAction.action = action ;
synchronized (mActions) {
final ArrayList<HandlerAction> actions = mActions ;
while (actions.remove(handlerAction)) {
// Keep going
}
}
}
//还是用handler 去执行 runnbale 任务
void executeActions(Handler handler) {
synchronized (mActions) {
final ArrayList<HandlerAction> actions = mActions ;
final int count = actions.size() ;
for ( int i = 0 ; i < count ; i++) {
final HandlerAction handlerAction = actions.get(i) ;
handler.postDelayed(handlerAction.action , handlerAction.delay) ;
}
actions.clear() ;
}
}
这个类会被调用 performTraversals 被执行
private void performTraversals() {
.....
//最终还是被handler执行
getRunQueue().executeActions(attachInfo.mHandler) ;
.....
}
.....
//最终还是被handler执行
getRunQueue().executeActions(attachInfo.mHandler) ;
.....
}
还是excuteActions 方法 他会循环去执行任务已经添的任务 用handler 去执行任务
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6589)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:942)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4541)
at android.view.View.invalidateInternal(View.java:11602)
at android.view.View.invalidate(View.java:11566)
at android.view.View.invalidate(View.java:11550)
at android.widget.TextView.checkForRelayout(TextView.java:6965)
at android.widget.TextView.setText(TextView.java:4101)
at android.widget.TextView.setText(TextView.java:3959)
这个异常
Only the original thread that created a view hierarchy can touch its views.
很熟悉,但是为什么会抛这个异常,这个异常代表的是什么 为什么我们要用handler 才能更新ui,不用handler的话 我们又为什么要在自线程中调用
Looper.prepare()
先看异常
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.") ;
}
}
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.") ;
}
}
简单的说 这个就是检测当前线程 如果不是ui线程 就会抛出这个异常 那为什么handler 可以直接更新 来看一下app的 入口
//java 程序入口 main 函数
//app 的真正入口
public static void main(String[] args) {
//启动一个简单的Dalvik分析器
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) ;
Process.setArgV0( "<pre-initialized>") ;
//看这里 把当前线程作为Looper 循环处理消息
Looper.prepareMainLooper() ;
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler() ;
}
//新建一个 ActivityThread 对象
ActivityThread thread = new ActivityThread() ;
//初始化信息
thread.attach( false) ;
//AsyncTask 获取handler 信息
AsyncTask.init() ;
if ( false) {
Looper.myLooper().setMessageLogging( new
LogPrinter(Log.DEBUG , "ActivityThread")) ;
}
//开始循环消息队列
Looper.loop() ;
throw new RuntimeException( "Main thread loop unexpectedly exited") ;
}
//初始化当前Thread作为循环器,标记当前线程为主looper
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 void prepareMainLooper() {
prepare( false) ;
synchronized (Looper. class) {
if (sMainLooper != null) {
throw new IllegalStateException( "The main Looper has already been prepared.") ;
}
sMainLooper = myLooper() ;
}
}
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) ;
}
//具体是哪个handler的消息 就用哪个handler 去分发消息
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.recycle() ;
}
}
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) ;
}
//具体是哪个handler的消息 就用哪个handler 去分发消息
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.recycle() ;
}
}
这个是具体消息分发的逻辑,但是这里如果是这样处理会有一个问题,当没有获取到消息的时候,会return掉,在看前面 ActivityThread 的main方法 ,如果looper返回,跳出这个循环 ,会抛出throw new RuntimeException("Main thread loop unexpectedly exited”); 这个异常信息,但是 这个异常 通常在开发过程中或者在异常解决中并不常见或者是都没有见过,肯定是在获取消息时对这个进行了处理 接着看
//获取下一个消息方法
final Message next() {
int pendingIdleHandlerCount = - 1 ; // -1 only during first iteration
int nextPollTimeoutMillis = 0 ; //默认0
for ( ;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands() ;
}
//调用native层进行消息标示 0立即返回 -1 等待
nativePollOnce(mPtr , nextPollTimeoutMillis) ;
synchronized ( this) {
if (mQuiting) {
return null;
}
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis() ;
Message prevMsg = null;
Message msg = mMessages ;
if (msg != null && msg.target == null) {
// Stalled by a barrier. Find the next asynchronous message in the queue.
do {
prevMsg = msg ;
msg = msg.next ;
} while (msg != null && !msg.isAsynchronous()) ;
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = ( int) Math.min(msg.when - now , Integer.MAX_VALUE) ;
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next ;
} else {
mMessages = msg.next ;
}
msg.next = null;
if ( false) Log.v( "MessageQueue" , "Returning message: " + msg) ;
msg.markInUse() ;
return msg ;
}
} else {
// No more messages. 没有消息 设置为-1
nextPollTimeoutMillis = - 1 ;
}
// If first time idle, then get the number of idlers to run.
// Idle handles only run if the queue is empty or if the first message
// in the queue (possibly a barrier) is due to be handled in the future.
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size() ;
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
mBlocked = true;
continue;
}
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount , 4)] ;
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers) ;
}
// Run the idle handlers.
// We only ever reach this code block during the first iteration.
for ( int i = 0 ; i < pendingIdleHandlerCount ; i++) {
final IdleHandler idler = mPendingIdleHandlers[i] ;
mPendingIdleHandlers[i] = null; // release the reference to the handler
boolean keep = false;
try {
keep = idler.queueIdle() ;
} catch (Throwable t) {
Log.wtf( "MessageQueue" , "IdleHandler threw exception" , t) ;
}
if (!keep) {
synchronized ( this) {
mIdleHandlers.remove(idler) ;
}
}
}
// Reset the idle handler count to 0 so we do not run them again.
pendingIdleHandlerCount = 0 ;
// While calling an idle handler, a new message could have been delivered
// so go back and look again for a pending message without waiting.
nextPollTimeoutMillis = 0 ;
}
}
static void android_os_MessageQueue_nativePollOnce(JNIEnv* env
, jobject obj
,
jint ptr , jint timeoutMillis) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr) ;
//调用pollOnce 方法
nativeMessageQueue->pollOnce(env , timeoutMillis) ;
}
jint ptr , jint timeoutMillis) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr) ;
//调用pollOnce 方法
nativeMessageQueue->pollOnce(env , timeoutMillis) ;
}
//jni层 pollOnce 方法的处理
void NativeMessageQueue::pollOnce(JNIEnv* env , int timeoutMillis) {
mInCallback = true ;
//这个是调用的Looper的 pollOnce 的方法
mLooper->pollOnce(timeoutMillis) ;
mInCallback = false ;
if (mExceptionObj) {
env->Throw(mExceptionObj) ;
env->DeleteLocalRef(mExceptionObj) ;
mExceptionObj = NULL ;
}
}
void NativeMessageQueue::pollOnce(JNIEnv* env , int timeoutMillis) {
mInCallback = true ;
//这个是调用的Looper的 pollOnce 的方法
mLooper->pollOnce(timeoutMillis) ;
mInCallback = false ;
if (mExceptionObj) {
env->Throw(mExceptionObj) ;
env->DeleteLocalRef(mExceptionObj) ;
mExceptionObj = NULL ;
}
}
//pollOne的实现
int Looper::pollOnce( int timeoutMillis , int* outFd , int* outEvents , void** outData) {
int result = 0 ;
for ( ;;) {
while (mResponseIndex < mResponses.size()) {
const Response& response = mResponses.itemAt(mResponseIndex++) ;
int ident = response.request.ident ;
if (ident >= 0) {
int fd = response.request.fd ;
int events = response.events ;
void* data = response.request.data ;
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - returning signalled identifier %d: "
"fd=%d, events=0x%x, data=%p" ,
this , ident , fd , events , data) ;
#endif
if (outFd != NULL) *outFd = fd ;
if (outEvents != NULL) *outEvents = events ;
if (outData != NULL) *outData = data ;
return ident ;
}
}
if (result != 0) {
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - returning result %d" , this , result) ;
#endif
if (outFd != NULL) *outFd = 0 ;
if (outEvents != NULL) *outEvents = 0 ;
if (outData != NULL) *outData = NULL ;
return result ;
}
//这个是关键
result = pollInner(timeoutMillis) ;
}
}
int Looper::pollOnce( int timeoutMillis , int* outFd , int* outEvents , void** outData) {
int result = 0 ;
for ( ;;) {
while (mResponseIndex < mResponses.size()) {
const Response& response = mResponses.itemAt(mResponseIndex++) ;
int ident = response.request.ident ;
if (ident >= 0) {
int fd = response.request.fd ;
int events = response.events ;
void* data = response.request.data ;
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - returning signalled identifier %d: "
"fd=%d, events=0x%x, data=%p" ,
this , ident , fd , events , data) ;
#endif
if (outFd != NULL) *outFd = fd ;
if (outEvents != NULL) *outEvents = events ;
if (outData != NULL) *outData = data ;
return ident ;
}
}
if (result != 0) {
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - returning result %d" , this , result) ;
#endif
if (outFd != NULL) *outFd = 0 ;
if (outEvents != NULL) *outEvents = 0 ;
if (outData != NULL) *outData = NULL ;
return result ;
}
//这个是关键
result = pollInner(timeoutMillis) ;
}
}
//这个方法是实现的关键 timeoutMillis如果是0 立刻返回 如果是 -1等待 释放资源
int Looper::pollInner( int timeoutMillis) {
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - waiting: timeoutMillis=%d" , this , timeoutMillis) ;
#endif
// Adjust the timeout based on when the next message is due.
if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC) ;
int messageTimeoutMillis = toMillisecondTimeoutDelay(now , mNextMessageUptime) ;
if (messageTimeoutMillis >= 0
&& (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
timeoutMillis = messageTimeoutMillis ;
}
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d" ,
this , mNextMessageUptime - now , timeoutMillis) ;
#endif
}
// Poll.
int result = ALOOPER_POLL_WAKE ;
mResponses.clear() ;
mResponseIndex = 0 ;
struct epoll_event eventItems[EPOLL_MAX_EVENTS] ;
//epoll_wait 这个是等待的具体实现
int eventCount = epoll_wait(mEpollFd , eventItems , EPOLL_MAX_EVENTS , timeoutMillis) ;
// Acquire lock.
mLock.lock() ;
int Looper::pollInner( int timeoutMillis) {
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - waiting: timeoutMillis=%d" , this , timeoutMillis) ;
#endif
// Adjust the timeout based on when the next message is due.
if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC) ;
int messageTimeoutMillis = toMillisecondTimeoutDelay(now , mNextMessageUptime) ;
if (messageTimeoutMillis >= 0
&& (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
timeoutMillis = messageTimeoutMillis ;
}
#if DEBUG_POLL_AND_WAKE
ALOGD( "%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d" ,
this , mNextMessageUptime - now , timeoutMillis) ;
#endif
}
// Poll.
int result = ALOOPER_POLL_WAKE ;
mResponses.clear() ;
mResponseIndex = 0 ;
struct epoll_event eventItems[EPOLL_MAX_EVENTS] ;
//epoll_wait 这个是等待的具体实现
int eventCount = epoll_wait(mEpollFd , eventItems , EPOLL_MAX_EVENTS , timeoutMillis) ;
// Acquire lock.
mLock.lock() ;
jni层先分析到这里,Looper 方法对没有消息进行了等待,然后在发送消息是进行了唤醒 ,具体什么时间设置-1 什么时间设置0 在MessageQueue 的next方法里面,当有消息的时候 就是0 没有的时候 就是-1.
handler发送消息最终调用的是 handler方法的
public boolean
sendMessageAtTime(Message msg
, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue ;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg , uptimeMillis) ;
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue") ;
Log.w( "Looper" , e.getMessage() , e) ;
}
return sent ;
}
{
boolean sent = false;
MessageQueue queue = mQueue ;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg , uptimeMillis) ;
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue") ;
Log.w( "Looper" , e.getMessage() , e) ;
}
return sent ;
}
final boolean enqueueMessage(Message msg
, long when) {
if (msg.isInUse()) {
throw new AndroidRuntimeException(msg + " This message is already in use.") ;
}
if (msg.target == null) {
throw new AndroidRuntimeException( "Message must have a target.") ;
}
boolean needWake ;
synchronized ( this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread") ;
Log.w( "MessageQueue" , e.getMessage() , e) ;
return false;
}
msg.when = when ;
Message p = mMessages ;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p ;
mMessages = msg ;
needWake = mBlocked ;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous() ;
Message prev ;
for ( ;;) {
prev = p ;
p = p.next ;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p ; // invariant: p == prev.next
prev.next = msg ;
}
}
if (needWake) {
//这里对消息队列进行了唤醒
nativeWake(mPtr) ;
}
return true;
}
if (msg.isInUse()) {
throw new AndroidRuntimeException(msg + " This message is already in use.") ;
}
if (msg.target == null) {
throw new AndroidRuntimeException( "Message must have a target.") ;
}
boolean needWake ;
synchronized ( this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread") ;
Log.w( "MessageQueue" , e.getMessage() , e) ;
return false;
}
msg.when = when ;
Message p = mMessages ;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p ;
mMessages = msg ;
needWake = mBlocked ;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous() ;
Message prev ;
for ( ;;) {
prev = p ;
p = p.next ;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p ; // invariant: p == prev.next
prev.next = msg ;
}
}
if (needWake) {
//这里对消息队列进行了唤醒
nativeWake(mPtr) ;
}
return true;
}
void NativeMessageQueue::wake() {
//这个是调用的Looper的 wake 的方法
mLooper->wake() ;
}
//这个是调用的Looper的 wake 的方法
mLooper->wake() ;
}
还有一种情况,如果在ui未展示出来之前,做在自线程设置ui数据,是不会报错的,这个和ui绘制流程有关系,有时间会在针对ui绘制 整理出一篇文章来。
现在总结一下写的这几个东西
Handler:负责消息发送消息和消息的处理。
MessageQueue:消息队列,负责消息的查询,和线程的等待与唤醒。
Looper:循环消息体,和负责消息的分发。
handler 将message发送过来,如果当前MessageQueue next 等待的话 就唤醒处理消息,looper循环去取Message 然后 分发给各个负责自己的handler 来处理消息 。