zoukankan      html  css  js  c++  java
  • Android handle 更新主线程的原理

    Android handle 更新主线程的原理

    1. handler的主要作用是用来更新主线程的UI,子线程向主线程发送信息。

    2.handler 的实现原理分析:

      1). handler的实现离不开Looper和MessageQueue。一个主线程只创建一个looper与之对应,looper会创建一个MessageQueue用来管理线程间的消息传递。

        在looper中有两个很重要的方法,一个是prepare()和loop()。prepare()方法会创建一个Looper对象放到当前线程中,实现一个线程只用一个Looper对象。

        在looper的构造方法中会创建一个消息队列,用来存放Message对象。

        在loop()方法中首先获取到当前的MessageQueue。并且有一个无线循环 得到队列中的Message( Message msg = queue.next();),当队列是空的时候循环阻塞,

        当得到Message 对象后会执行,msg.target.dispatchMessage(msg);  其实这里的msg.target 就是调用sendMessage()的的handler的对象,

      2). handler这个对象中的方法有:

        

    public void dispatchMessage(Message msg) {

        if (msg.callback != null) {
    handleCallback(msg);
    } else {
    if (mCallback != null) {
    if (mCallback.handleMessage(msg)) {
    return;
    }
    }
    handleMessage(msg);
    }
    }

    这个方法会调用Handle 中的我们自己实现的 handleMessage方法。

    当我们new一个handler的时时候,构造方法会执行以下的方法。
    public Handler() {
    this(null, false);
    }
    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();
    if (mLooper == null) {
    throw new RuntimeException(
    "Can't create handler inside thread that has not called Looper.prepare()");
    }
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
    }
    这行代码是获取到当前线程的looper,(mLooper = Looper.myLooper();) 在Looper中有 myLooper() 这个静态的方法是得到当前线程的Looper
    looper中的代码
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>()
    public static Looper myLooper() {
    return sThreadLocal.get();
    }

    Handler类中
    public final boolean sendMessage(Message msg)
    {
    return sendMessageDelayed(msg, 0);
    }

    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
    if (delayMillis < 0) {
    delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    if (queue == null) {
    RuntimeException e = new RuntimeException(
    this + " sendMessageAtTime() called with no mQueue");
    Log.w("Looper", e.getMessage(), e);
    return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
    }

    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
    msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
    }

    当我们调用handler中的 sendMessage()时,最终会调用 enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) 这个方法。
    这个方法中有 这样的一句 msg.target = this;就可以看出来,msg.targe 就是handler这个对象。这个会在looper 的loop方法中调用 dispatchMessage(Message msg) 这个方法。
     




    
    


     
  • 相关阅读:
    CentOS 8.0配置阿里云yum源和epel源
    CentOS8 安装epel 使用阿里云镜像
    centos下yum使用proxy代理方法
    MySQL中的事务控制(一)start transaction
    MySQL中的锁定语句: lock tables 和 unlock tables
    MySQL中的触发器
    MySQL中的事件调度器
    MySQL中的流程控制
    MySQL中的不可见索引、倒序索引
    IDEA出现Push to origin/master was rejected
  • 原文地址:https://www.cnblogs.com/guoke-jsp/p/5113174.html
Copyright © 2011-2022 走看看