How the Main Thread works

According to Droidcon NYC 2015 - How the Main Thread works
Michael Bailey | YouTube

Main Thread

1.Looper | Message Queue | Handler

A. android.os.Looper
package android.app;
/**
 * This message the execution of the main thread in an
 * application process, scheduling and executing activities,
 * broadcasts, and other operations on it as the activity
 * manager requests.
 */
 public final class ActivityThread {
 <omitted>
  public static void main(String[] args) {
     <omitted>
     Looper.prepareMainLooper();
     ActivityThread thread = new ActivityThread();
     thread.attach(false);
     <omitted>
     Looper.loop();
     throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  }
Class used to run a message loop for a thread
  • A thread has zero or one Loopers
  • It has a looper, if you call Looper.prepare();
  • It is running an message loop if you call Looper.loop();
Looper.loop()
public final class Looper {
  /** Run the message queue in this thread. Be sure to call
   * {@link #quit()} to end the 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;
      }
      msg.target.dispatchMessage(msg);
    }
  }
}
B.Message Queue
Internally(non-public API):
  • A queue of Message to be processed at a given time
  • next() returns the next message that should be processed. Will not return Messages that will be processed at future times.
  • Timing based on SystemClock.uptimeMillis() (CPU time)
Message
  • when - earliest time it can be processed
  • Processing, either
    • callback.run() (Runnable)
    • OR target.handleMessage(message)
  • obtain()/release() from an Object pool

How can Messages be added to the MessageQueue for processing?

C. Handler
  • Add message to the MessageQueue
    • post()
    • postDelayed()/postAtTime()
    • postAtFrontOfQueue() <- @piwai says do not use it
  • Process messages with no Callback at the front of the MessageQueue
    • handleMessage()
  • Start new Handler
    • new Handler();
    • new Handler(Looper.getMainLooper());
    • new Handler(Looper.myLooper());
D.DrawHandler –> Choreographer
  • Manages Frame Drawing on the Main Thread.
    This is responsible for basically getting frames displayed and pushing the UI code putting the messages on there so the UI code gets pushed to the GPU and drawing on the screen
/* From Android API 22 sdk source*/
FrameHandler handler = new FrameHandler(Looper.myLooper());
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
handler.sendMessageAtTime(msg, nextFrameTime);

private final class FrameHandler extends Handler {
  public FrameHandler(Looper lopper) {
    super(looper);
  }
  @Override
  public void handleMessage(Message msg) {
    switch(msg.what) {
      case MSG_DO_FRAME:
        doFrame(System.nanoTime(), 0);
        break;
      case MSG_DO_SCHEDULE_VSYNC:
        doScheduleVsync();
        break;
      case MSG_DO_SCHEDULE_CALLBACK:
        doScheduleCallback(msg.arg1);
        break;
      }
    }
  }

RenderThread

  • New in API 21+
  • Offloads pushing UI to the GPU to a non-main thread
  • If something takes too long on the main thread, bad things can happen:
    • Drop frame
    • Input events don’t get processed
    • ANR

Android thread rules:
From the Android docs:
“Thus, there are simply two rules to Android’s single thread model:”

  • Do not block the UI thread
  • Do not access the Android UI thread tookit from outside the UI thread.

Other thread

How do you run stuff NOT on the main thread
  • java.util.concurrent
  • AsyncTask
  • RxJava

StrictMode

http://developer.android.com/reference/android/os/StrictMode.html

if (DEVELOPER_MODE) {
  StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
      .detectDiskReads()
      .detectDiskWrites()
      .detectNetwork()
      .penaltyLog()
      .build());
  StrictMode.setVmPolicy(new StrictMode.Vmpolicy.Builder())
      .detectLeakedSqlLiteObjects()
      .detectLeakedClosableObjects()
      .penaltyLog()
      .penaltyDeath()
      .build());
}

Instrumentation Thread (Test thread)

  • From Android API 22 sdk source
public class Instrumentation {
  /**
   * Create and start a new thread in which to tun instrumentation.
   * This new thread will call to {@link #onStart} where
   * you can implement the instrumentation.
   */
  public void start() {
    <omitted>
    mRunner = new InstrumentationThread("Instr: " + getClass().getName()); 
    mRunner.start();
  }
}

Activity Lifecycle Events

  • Activity Lifecycle Events (startActivity(), finish()) go out of your process through Binder IPC to the ActivityManager
  • Then back onto your main queue in the form of lifecycle callbacks (onCreate(), onDestroy()..).

SyncBarriers

  • No synchronous messages will be processed if a sync barrier is in place. It must be removed first.
  • Asynchronous Messages will continue to be processed even when a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值