zoukankan      html  css  js  c++  java
  • 【读书笔记】Android Handler和Looper流程

    最近在阅读《Android系统源代码情景分析》,记录一下Android Handler和Looper流程。

    Looper由ActivityThread.main()创建并启动消息循环,ActivityThread.main()代码如下:

    public static void main(String[] args) {
    
            ...
    
            //创建Lopper
            Looper.prepareMainLooper();
    
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
    
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
    
            //为AsyncTask指定MainLooper,使得AsyncTask的回调函数运行在主线程上
            //此代码在5.1之后被移除
            AsyncTask.init();
    
            //开启消息循环
            Looper.loop();
    
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }

    调用Looper.prepareMainLooper()之后,创建静态的的Looper对象sMainLooper,并将Looper对象存放到ThreadLocal<Looper>里面。在不同线程下可以通过调用Looper.myLooper()创建自己的消息循环其实就是利用ThreadLocal<Looper>来实现的。

    Looper的准备流程图如下:

    当进入Looper.loop()之后,会读取MessageQueue里面的消息,如果消息队列为空则睡眠等待,直到通过Handler.sendMessage()将Message放入到MessageQueue才会唤醒,流程如下:

    将Message放入到MessageQueue之后,Looper.loop()则会取出Message,然后通过msg.target.dispatchMessage(msg)进入到处理消息流程:

    如此就会进入到Handler.handleMessage()里面,平时Handler的使用就是覆写Handler.handleMessage()来处理消息,调整UI的。

    PS:

    1、new Handler()无参构造函数默认调用Looper.myLooper(),如果在另外的子线程中调用而没有先调用Looper.prepare()则会抛出RuntimeException("Can't create handler inside thread that has not called Looper.prepare()")异常;

    如果在子线程中也想调用主线程中的消息循环,那么必须通过new Handler(Looper.getMainLooper())传递主线程的Looper;

    2、由于Looper.prepareMainLooper()已经在ActivityThread中调用了,如果在其他地方调用则会出错,因此Looper.prepareMainLooper()不应该被调用;

    3、如果想要使用与界面无关的消息循环,建议使用HandlerThread;

    4、如果想要使用与界面有关的消息循环,建议使用AsyncTask。

  • 相关阅读:
    MySQL "show users"
    MySQL
    A MySQL 'create table' syntax example
    MySQL backup
    MySQL show status
    Tomcat, pathinfo, and servlets
    Servlet forward example
    Servlet redirect example
    Java servlet example
    How to forward from one JSP to another JSP
  • 原文地址:https://www.cnblogs.com/alexthecoder/p/5098905.html
Copyright © 2011-2022 走看看