打开Handler
的API文档后,我们会看到它的四个构造方法,以及其中两个的带有的长长的不推荐及其原因注释
// 不推荐的构造方法
public Handler();
public Handler(Handler.Callback callback);
// 推荐构造方法
public Handler(Looper looper);
public Handler(Looper looper, Handler.Callback callback);
推荐的构造方法中都需要明确传入Looper
对象。这是因为隐式指定Looper
对象具有很大的隐患。
虽然每一个线程只能存在一个Looper
对象,但开启一个新的线程并不会自动创建一个新的Looper
对象(主线程除外,创建主线程时会自动创建一个Looper
对象)。如果我们打算从主线程发送Message
到子线程处理,如果没有在子线程创建一个新的Looper
对象,然后new Handler()
这样创建Handler
对象就会抛出错误,程序崩溃。
显式指定Handler
关联的Looper
对象比起让Handler
隐式选择一个Looper
对象的好处显而易见:它能避免Handler
关联到不是你所期望的线程,还能给你提个醒,让你记得在需要的时候,给子线程开个Looper
来提取Message
。
怎么样获得主线程的Looper?
Looper有一个静态方法,可以获取到主线程的Looper
public static Looper getMainLooper ();