俗话说 Handler机制
Handler
Handler, 快递员
MessageQueen 投递站
Looper 理解为报告系统
通过Handler 可以发快递,也可以收快递
handMessage 对应: 投递员从投递站中取到快件后会根据快件的信息送到客户手中,
sendMessage 对应: 投递员从多个客户手中收到要寄送的快递,送回自己所属的快递站
looper 对应: 快递站每隔一定时间会来一辆拖运车将快递站收到的快递一件一件的拉走,发到目标地的快递站
目的地的快递员从从投递站中取到快件后会根据快件的信息送到客户手中,这一步又回到handMessage
快递员只能处理所属公司快递站的快件进行投或送
Handler只能处理自己归属MessageQueen收发的Message
快递公司只能让一套物流轮循系统收集自己属下快递站的快件,不可能有多个分支物流同时处理
当前线程,只能有一个looper来循环MessageQueen进行收发消息
一个线程只能有一个looper, prepare为创建looper的方法
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
//每个线程只能有一个looper存在
}
sThreadLocal.set(new Looper(quitAllowed));
}
快递站建立,物流系统必备的,
looper创建的时候伴生着Messagequeen
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
一个looper对应一个Messagequeen
快递公司新开辟市场,想新招快递员,这个时候因为当地的物流站还未建立,没有物流系统,那么快递员这个时候是没有服务对象,还没有正式加入到物流链中,所以这个时候新招快递员是个失败的决策
在子线程中直接创建Handler会报异常,因为looper还没有创建,
因为在创建handler的过程中会去取当前线程的looper对象,直接创建的话lopper对象还没有创建出来,所以会报异常.
所以,要想在子线程中创建handler,必须先调用looper.prepare方法先创建出looper来
public Handler(Callback callback, boolean async) {
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(); //此处获取当前线程的looper
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
所以正确的打开姿势:
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare(); //创建物流站,对接物流系统
Handler handler = new Handler();//招聘快递员
Looper.loop(); //启动物流系统
}
}).start();