顾名思义,UI线程就是刷新UI所在的线程。
我们知道UI是单线程刷新的,那么UI线程是哪个线程?换一个问法:UI线程==主线程吗?
这里我们提出两个方法:Activity.runOnUiThread(Runnable)、View.post(Runnable)。
我们先看一下runOnUiThread方法:
final void runOnUiThread(Runnable action){ //判断当前的thread是不是UIthread if(Thread.currentThread() != mUiThread){ //不是就post到消息队列里面 mHandler.post(action); }else{ //是的话就直接run action.run(); } } //看看mUiThread和mHandle在哪里初始化的, //mHandler是Activity里面的全局变量,在Acitivity创建时就一起创建了 //它创建的时候没有指定looper,所以创建Activity对象时在哪个线程,那handler就用的是哪个线程的looper final Handler mHandler = new Handler(); //mUiThread //它在调用Activity的attach函数的时候赋值的 //attach是在activity启动的时候调用的 final void attach(Context context,...){ ... mUiThread = Thread.currentThread(); ... }
所以对于Activity来说,UI线程就是主线程。
然后我们再来看一下View.post(Runnable)的方法的代码:
public boolean post(Runnable action){ final AttachInfo attachInfo = mAttachInfo; //1,attachInfo不为null,把action post到mHandler里面。 if(attachInfo != null){ return attachInfo.mHandler.post(action); } //2,attachInfo是null,把action post 到 ViewRootImpl的runQueue ViewRootImpl.getRunQueue().post(action); return true; }
这里的attachInfo是在ViewRootImpl构造函数里面创建的,attachInfo里面的mHandler对应的就是ViewRootImpl对象创建时所在的线程。因为ViewRootImpl是在onResume的时候创建的,所以如果你在Activity的onCreate就用View post了一个Runnable,就会放到RunQueue里面,等ViewRootImpl创建好后,再丢到VIewRootImpl所在线程处理。不管哪种情况,最后都要丢到ViewRootImpl的线程处理。
所以对于View来说,UI线程就是ViewRootImpl创建时所在的线程。