2016년 7월 18일 월요일

android sendMeassge 분석




sendMessage 호출시 내부적으로는 sendMessageDelayed 0 가 호출되는 형태로 되어있습니다.
아래 빨간색으로 표시된
334            Message p = mMessages;
부분은 현제 메세지를 의미합니다. 해당 메세지에서 when 값을 보고 앞에 넣을것인지 중간에 넣을 것인지 결정하게됩니다.
sendMessage는 Queue 에 값을 넣는 부분까지만 있습니다.

아마도 큐에서 꺼내가는 부분은
362            if (needWake) {
363                nativeWake(mPtr);
364            }
위 빨간색으로 되어있는 부분서 처리할것 같은데 그건 좀 더 분석해봐야 할것 같습니다.


505    public final boolean sendMessage(Message msg)
506    {
507        return sendMessageDelayed(msg, 0);
508    }



565    public final boolean sendMessageDelayed(Message msg, long delayMillis)
566    {
567        if (delayMillis < 0) {
568            delayMillis = 0;
569        }
570        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
571    }


592    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
593        MessageQueue queue = mQueue;
594        if (queue == null) {
595            RuntimeException e = new RuntimeException(
596                    this + " sendMessageAtTime() called with no mQueue");
597            Log.w("Looper", e.getMessage(), e);
598            return false;
599        }
600        return enqueueMessage(queue, msg, uptimeMillis);
601    }



626    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
627        msg.target = this;
628        if (mAsynchronous) {
629            msg.setAsynchronous(true);
630        }
631        return queue.enqueueMessage(msg, uptimeMillis);

632    }



315    boolean enqueueMessage(Message msg, long when) {
316        if (msg.target == null) {
317            throw new IllegalArgumentException("Message must have a target.");
318        }
319        if (msg.isInUse()) {
320            throw new IllegalStateException(msg + " This message is already in use.");
321        }
322
323        synchronized (this) {
324            if (mQuitting) {
325                IllegalStateException e = new IllegalStateException(
326                        msg.target + " sending message to a Handler on a dead thread");
327                Log.w("MessageQueue", e.getMessage(), e);
328                msg.recycle();
329                return false;
330            }
331
332            msg.markInUse();
333            msg.when = when;
334            Message p = mMessages;
335            boolean needWake;
336            if (p == null || when == 0 || when < p.when) {
337                // New head, wake up the event queue if blocked.
338                msg.next = p;
339                mMessages = msg;
340                needWake = mBlocked;
341            } else {
342                // Inserted within the middle of the queue.  Usually we don't have to wake
343                // up the event queue unless there is a barrier at the head of the queue
344                // and the message is the earliest asynchronous message in the queue.
345                needWake = mBlocked && p.target == null && msg.isAsynchronous();
346                Message prev;
347                for (;;) {
348                    prev = p;
349                    p = p.next;
350                    if (p == null || when < p.when) {
351                        break;
352                    }
353                    if (needWake && p.isAsynchronous()) {
354                        needWake = false;
355                    }
356                }
357                msg.next = p; // invariant: p == prev.next
358                prev.next = msg;
359            }
360
361            // We can assume mPtr != 0 because mQuitting is false.
362            if (needWake) {
363                nativeWake(mPtr);
364            }
365        }
366        return true;
367    }




























댓글 없음:

댓글 쓰기