Handler机制与注意

2017-09-20  本文已影响0人  pascalb

关于Handler可能很多初学者有疑问,根据个人的经验整理了下面的笔记,希望能给大家有所帮助

什么是Handler机制

Handler机制是为了在子线程中通知UI线程(主线程)处理提供的一套机制
两个主要基本作用
1:延迟执行messages或runnables

关于Handler机制的几个问题
1:为什么要通过Handler来更新UI
: 1:如果直接在UI(主线程)中处理复杂的逻辑或者网络请求等,很容易造成ANR
: 2:Handler机制提供了MessageQueue确保消息的有序的处理

2:子程中是否可以创建Handler
: 可以,主线程可以通过这个Handler来发送信息给子线程,后面会以代码事例说明

逐步了解Handler

Handler机制的实现,必须得知道Message、MassageQueue以及Looper.下面一个个介绍下

Message
: Message主要是包含了消息体,用于发送给Handler

//获取Message实例的方式
Message msg1 = Message.obtain();
//或
Message msg2 = Handler.obtainMessage();

//Message实例
public final class Message implements Parcelable {
    public int what;
    public int arg1; 
    public int arg2;
    public Object obj;
    ...
    }

//Post实例问题
 new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                //这边是获取实例
                Message msg = Message.obtain();
            }
        }, 500);
//Post发送的不是Message?我们看下面的代码的实现

public final boolean postDelayed(Runnable r, long delayMillis)
{
    return sendMessageDelayed(getPostMessage(r), delayMillis);
} 
//调用getPostMessage获取的Message方法
private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
}

//优化delayMillis的实现,
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
    if (delayMillis < 0) {
    delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
//加入到消息队列,mQueue 在Handler声明时就注册
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);
}



MessageQueue
MessageQueue: 消息队列 最后会调用使用Looper.myQueue()方法。主线程的已经实现了Looper,子线程的Looper要自己实现

Looper
作用就是开始消息的轮询, 主线程中已经实现了Looper,子线程中要自己实现,实现如下

class LooperThread extends Thread {
        public Handler mHandler;
  
        public void run() {
            Looper.prepare();
  
            mHandler = new Handler() {
                public void handleMessage(Message msg) {
                    // process incoming messages here
                }
            };
  
            Looper.loop();
        }
        

//那么主线程中是怎么实现的,看main方法的实现
 public static void main(String[] args) {
        ...
        //初始化Looper
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}
//在main函数中已经实现了,所以不用我们自己再次实现

Handler
Handler消息的发送才和接收者

通过这Message、MassageQueue以及Looper的分析。相信应该可以很清楚的了解了Handler机制

最后提供一张图可以更清楚的了解这中间过程


这里写图片描述

想更清楚的查看源码请看自己在线查看
//API查看
https://developer.android.com/training/index.html
//5.0以前的代码查看
http://www.grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/
//官方源码查看
https://android-review.googlesource.com/

上一篇下一篇

猜你喜欢

热点阅读