日更(十八)-Android-Looper是个什么东西

瞎扯

昨天写了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

2739107-23f7b642730c7a58.png
image.png

这个ServiceThread是什么鬼

2739107-3814f0711e18c53a.png
image.png

是不是我前面说的那么回事.哈哈

2739107-5ed308d4d86ff3e0.png
image.png

总结:

AMS,启动了主线程. 然后我们写的所有activity,fragment之类的代码,什么onCreate,onStart里的代码.
其实都相当于,执行在Looper.loop()里面.通过handler发送消息.处理消息在不停的调用.方法调方法这样不停的.如果你不停的debug下一行,就会发现跑到Looper里面去了.就是这么个道理.
所以,当我们某个UI更新操作逻辑过于复杂,就会出现卡死的情况.
onstart,onparse等生命周期里面逻辑太复杂也会造成ANR.因为主线程走不下去了.肯定没法响应啊.

主线程的Looper退出循环,意味着,主线程结束,程序退出.


您的喜欢与回复是我最大的动力-_-
交流群:493180098

猜你喜欢

转载自blog.csdn.net/weixin_34358365/article/details/86984776
今日推荐