Looper
Looper.prepare() 에서 스레드 별로 Looper를 생성 한다, Looper 생성자에서는 Looper에서 가지는 MessageQueue도 생성한다.
생성된 Looper는 ThreadLocal<Looper> sThreadLocal 에 저장된다. Looper.loop() 를 호출 하면 sThreadLocal 에서 Looper를 꺼내와서 사용한다.
MainLooper는 ActivityThread 의 main() 함수에서 Looper.prepareMainLooper() 로 생성 하였으므로, Looper.getMainLooper()를 호출 하여 가져올 수 있다.
loop() 메서드 에서는 루프를 도며 MessageQueue 에서 Message를 가져와서 msg.target.dispatchMessage(msg); 를 호출 하여 메시지를 처리한다. 여기서 target은 Handler 이다.
MessageQueue 에서 다음 Messsage를 가져오는 next() 에서 blocking 상태로 대기하다가 Message가 있으면 return 해준다.
next() 에서 blocking 상태 이기 때문에 loop() 메서드는 종료 되지 않는다. loop() 메서드를 종료 하기 위해서는 Looper의 quit(), quitSafely() 메서드를 호출 해야 한다. quit(), quitSafely() 메서드가 호출 되면 MesssageQueue에서 next() 로 null 인 Message 를 리턴해 주어 loop() 메서드를 종료 시킨다.
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;
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
try {
msg.target.dispatchMessage(msg);
end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
...
msg.recycleUnchecked();
}
}
Message
private static Message sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
Handler
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
'Android.log' 카테고리의 다른 글
[이슈] Stetho 로 Sqlite 쿼리 실행 안되는 문제 (0) | 2019.03.08 |
---|---|
코드로 View 에 id 지정하기 (1) | 2019.01.30 |
안드로이드 메인클래스 (0) | 2019.01.06 |
[Kotlin] RecyclerView 샘플 (3) | 2018.09.11 |
[31 Days Of Kotlin - 1일차] let, apply, with, run (0) | 2018.08.09 |