本文基于:
http://blog.csdn.net/guolin_blog/article/details/9991569
(不得不说,郭霖真大神@。@)
摘至:
http://blog.csdn.net/lmj623565791/article/details/47079737
1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。
2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。
3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue想关联。
4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。
5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法
子线程更新UI方法:
- Handler的post()方法
- View的post()方法
- Activity的runOnUiThread()方法
- Handler的sendMessage()方法
由上文网址得知:
1、2、3的方法最后都是用handler的sendMessage方法的,所以下文根据网址总结下handler的处理过程。
前言
Android UI线程是不安全,一般处理都是new Handler(),并在里面handleMessage可以在UI线程处理sendMessage发回来的信息。
注意点
- Handler是依附于创建时所在的线程
- Handler()的实现需要一个Looper,(Looper里面有一个MessageQueue在不停循环)
- 一个线程只有一个Looper(原因详看下文Looper.prepare源码)、也就决定了一个线程只有一个Looper.
具体过程
new Handler()源码(抄至上文网址):
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}
可见handler是依靠Looper.myLooper()不为null时起效。我们直接new Handler() 也没new 过Looper呀,怎么它自己就不为null生效了?
Looper.myLooper()源码:
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
所以(Looper)sThreadLocal.get()决定Handler的生死。
(Looper)sThreadLocal.get()的出生是Looper.prepare决定的。
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
现在总结:
Looper.prepare()→sThreadLocal.set()!=null→sThreadLocal.get()!=null→Looper.myLooper()!=null→new Handler()
一切的成功的基础是Looper.prepare()。那问题来了:Looper我们也没处理过啊。
其实首先,Android程序的运行入口点可以认为是android.app.ActivityThread类的main()方法;
然后main线程一建立就帮我们
Looper.prepareMainLooper(){prepare()}&&Looper.loop;
所以最后总结下
main线程handler的实现过程:
main()→Looper.prepareMainLooper()→Looper.prepare()→sThreadLocal.set()!=null→sThreadLocal.get()!=null→Looper.myLooper()!=null→new Handler()
其他线程用Handler的实现过程:
new Thread()→Looper.prepare()→...→new Handler()
总结:
main线程入口帮我们:
Looper.prepareMainLooper(){Looper.myLooper()};
所以 平常 我们直接:
new Handler();
其他线程没有Looper.myLooper(),所以我们需要如下写:
new Thread() → Looper.prepare()→new Handler() →Looper.loop();
示例代码:
public class MainActivity extends Activity {
private Handler handler1;
private Handler handler2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler1 = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
handler2 = new Handler();
Looper.loop();
}
}).start();
}
}
Handler的sendMessage()实现过程
进:
handler.sendMessage(msg)
↓
queue.enqueueMessage(msg)
↓
queue.next()!=null;
出:
Looper.loop 一直循环
↓
if(queue.next()!=null) {handler.dispatchMessage(msg)}
↓
handler.handleMessage(msg);