瞎扯
昨天写了bus的生产者与消费者.
今天就写写looper
为什么不和handler一起写呢?因为懒.
Looper
loop翻译一下,回路,循环
大致就是循环的意思.
android里也一样.一个可以无限的死循环
其实大部分人应该都知道looper是个循环,不断的取消息,然后调用handler处理.
启动过程:
翻一下Handler的源码
构造函数.里的一段
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
handler必须持有一个Looper对象
Looper对象怎么来?
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
Looper.prepare()
应该很熟悉吧.
再来一段代码,子线程中创建Handler:
public void test() {
new Thread(){
@Override
public void run() {
super.run();
Looper.prepare();
Handler handler = new Handler();
Looper.loop();
}
}.start();
}
经历不深的人,看着这一段,肯定是懵的.
为什么调下Looper.prepare()
就行了.怎么跟handler联系上的.
调Looper.loop();
的干嘛?
Looper怎么跟handerl关联上的.明天再写.哈哈
今天就写为什么要调Looper.loop();
写份伪代码你应该就明白了.
public void test2() {
new Thread() {
@Override
public void run() {
super.run();
Looper looper = new Looper();//创建Looper,
Handler handler = new Handler(looper);//handler绑定looper
looper.loop();//looper开启循环
}
}.start();
}
public class Looper {
public Looper prepare() {
return new Looper();
}
public void loop() {
for (; ; ) {
// msg.target.dispatchMessage(msg);
handler.dispatchMessage(msg);//死循环,调用handler的回调处理结果.
}
}
}
去掉那些复杂的代码.
其本质差不多就这样,略过了MessageQueue
.
MessageQueue
就是个有序队列,其实没啥好讲的.一个集合而已.
looper.loop();为什么要在线程的最后调用?
因为死循环啊...不在最后调用在哪调用.
还有为了让这个线程不结束啊.
不信可以试试在loop()
后面再写代码.你看会不会往下走- -
把方法里的内容展开一下
new Thread() {
@Override
public void run() {
super.run();
Looper looper = new Looper();
Handler handler = new Handler(looper);
for (; ; ) {
// msg.target.dispatchMessage(msg);
handler.dispatchMessage(msg);
}
//如果不手动调用,looper怎么工作呢, 并且保证执行在线程的最后面- -
//可以试试,不调用loop(), handler会不会的回调会不会走.
}
}.start();
看看ams中如何创建的主线程的handler,looper
image.png这个ServiceThread
是什么鬼
是不是我前面说的那么回事.哈哈
image.png总结:
AMS,启动了主线程. 然后我们写的所有activity,fragment之类的代码,什么onCreate,onStart里的代码.
其实都相当于,执行在Looper.loop()里面.通过handler发送消息.处理消息在不停的调用.方法调方法这样不停的.如果你不停的debug下一行,就会发现跑到Looper里面去了.就是这么个道理.
所以,当我们某个UI更新操作逻辑过于复杂,就会出现卡死的情况.
onstart,onparse等生命周期里面逻辑太复杂也会造成ANR.因为主线程走不下去了.肯定没法响应啊.
主线程的Looper退出循环,意味着,主线程结束,程序退出.
您的喜欢与回复是我最大的动力-_-
交流群:493180098
网友评论