Handler handler = new Handler();
public Handler(Callback callback, boolean async) {
//省略若干源码...
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
}
Looper.myLooper()
获取当前线程绑定的Looper
对象,为什么这么说呢?那就要通过Looper的源码来分析了。mLooper.mQueue
获取消息队列static final ThreadLocal sThreadLocal = new ThreadLocal();
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
Looper.prepare()
对它进行初始化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));
}
Looper
对象并绑定到当前线程Looper.prepare()
进行初始化MessageQueue
的初始化又在哪里呢?当然是在Looper
的构造函数中啦private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Handler
的时候必须先调用Looper.prepare()
方法,但是我们平常使用的时候并没有调用它那为什么也是可以的呢?答案当然是:系统为你调用好了、那系统又在哪里调用的呢?ActivityThread.java
(这个类并不是一个线程只是一个简单的java类)源码中的main()
函数,可以看到如下代码:public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
//省略若干代码....
Process.setArgV0("" );
//初始化我们的主线程
Looper.prepareMainLooper();
//省略若干代码....
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//省略若干代码....
//进行无限死循环,当然在loop内部都是通过 线程的等待唤醒机制进行死循环的(节约资源)
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
handler.sendMessage(msg)
发送一条消息:handler.sendMessage(msg)
//调用上面这行代码,我们继续跟踪源码,发现最终调用了如下代码
//将消息添加进MessageQueue中,并唤醒Looper.loop()中的等待 把消息取出。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
handler发送一条消息——>放入MessageQueue中——>Looper.loop()死循环 取出消息 回传给handler
Looper
了new Thread(new Runnable() {
@Override
public void run() {
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};
}
}).start();
可以看到:系统抛出了一个RuntimeException 提示需要调用Looper.prepare()
那对代码改造一下:
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};
Looper.loop();
}
}).start();
创建好了handler 最后肯定还是要调用Looper.loop()的,不然消息只是放进去了并没有取出。
Looper.loop()
对主线程进行死循环,那Activity的生命周期或者其他的UI更新操作是怎么进行的呢?这里还是要继续查看ActivityThread.java
这个类的main()
函数源码进行解释:public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
//省略若干代码....
Process.setArgV0("" );
//初始化我们的主线程
Looper.prepareMainLooper();
//省略若干代码....
//获取更新ui操作或者其他操作的handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//省略若干代码....
//进行无限死循环,当然在loop内部都是通过 线程的等待唤醒机制进行死循环的(节约资源)
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
sMainThreadHandler
Handler对象,那这个对象有什么用呢,下面在告诉你。sMainThreadHandler
后执行了Looper.loop();
对主线程进行死循环 //将主线程退出
Looper.getMainLooper().quit();
run
函数中的代码执行完毕那么线程就会自动退出的,那我们的主线程是肯定是不可以退出的(上面已经演示过了),所以主线程最后进行了Looper.loop();
让线程进入一个死循环这样线程就一直在运行了。sMainThreadHandler
对象了,它是ActivityThread
中的一个内部类class H extends Handler{}
,Activity的一些生命周期回调函数都是通过这个来进行回调的。我们来查看一下这个H
类里的handlerMessage(Message msg)
函数 public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case PAUSE_ACTIVITY_FINISHING: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
// 截取了部分代码,感兴趣的可以查看下源码
}
原因:创建一个Handler的时候 同时也创建好了Looper 创建Looper的时候又创建好了MeessageQueue 这些都是在主线程中创建的(Handler一般都在主线程进行初始化),这样当你在其他任何线程中发送一条消息的时候,消息都是在MeessageQueue中,Looper循环从MeessageQueue中取出消息在调用
msg.target.dispatchMessage(msg);
这样消息就回到了创建Handler的地方 也就是主线程中。(如有错误还望指出)
public class MyHandler {
/**
* 消息拦截
*/
private MyCallback mCallback;
/**
* 轮询器
*/
private MyLooper looper;
/**
* 消息队列
*/
private MyMessageQueue queue;
public MyHandler() {
this(null);
}
/**
* handler 进行初始化
* 1.获取当前线程所绑定的Looper对象
*/
public MyHandler(MyCallback mCallback) {
looper = MyLooper.myLooper();
if (looper == null) {
throw new RuntimeException("如果当前线程未初始化Looper对象,则需要调用Looper.prepare();");
}
this.mCallback = mCallback;
queue = looper.queue;
}
/**
* 处理消息
*/
public void handleMessage(MyMessage msg) {
}
/**
* 对消息进行分发
*/
public void dispatchMessage(MyMessage msg) {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
/**
* 发送一条消息
*/
public final boolean sendMessage(MyMessage msg) {
//...中间一系列函数调用,最终执行如下重点代码
msg.target = this;
return queue.enqueueMessage(msg);
}
/**
* 用来拦截handler发送的消息
*/
public interface MyCallback {
boolean handleMessage(MyMessage msg);
}
}
public class MyMessage {
public int what;
public int arg1;
public int arg2;
public Object obj;
public MyHandler target;
public MyHandler getTarget() {
return target;
}
public void setTarget(MyHandler target) {
this.target = target;
}
public void sendToTarget() {
target.sendMessage(this);
}
}
public class MyLooper {
/**
* ThreadLocal 内部维护着一个 ThreadLocalMap(类似HashMap)以key value形式存储
* key:当前创建Looper对象的线程
* value: Looper对象
*/
static final ThreadLocal sThreadLocal = new ThreadLocal<>();
/**
* 当前所在线程
*/
private final Thread mThread;
/**
* 消息队列
*/
public final MyMessageQueue queue;
/*
* 初始化MyLooper对象并绑定他所在的线程
* 一个线程内部维护着同一个(Handler Looper MessageQueue)
*/
public static void prepare() {
sThreadLocal.set(new MyLooper());
}
/**
* 初始化消息队列
*/
private MyLooper() {
queue = new MyMessageQueue();
mThread = Thread.currentThread();
}
/**
* 返回与当前线程关联的Looper对象
* 返回null 则线程中没有初始化一个Looper对象
*/
public static MyLooper myLooper() {
return sThreadLocal.get();
}
public static void loop() {
/**
* 在Looper 源码 loop 函数中
* 使用将消息发送回handler
*
msg.target.dispatchMessage(msg);
*/
MyLooper looper = myLooper();
MyMessageQueue queue = looper.queue;
for (; ; ) {
MyMessage msg = queue.next();
if (msg != null) {
msg.target.dispatchMessage(msg);
}
}
}
}
public class MyMessageQueue {
private int position = 0;
/**
* 存储消息
*/
private List list = new ArrayList<>();
/**
* 添加一条消息
*
* @return 是否添加成功
*/
public boolean enqueueMessage(MyMessage msg) {
synchronized (this) {
//省略落干源码
list.add(msg);
}
return true;
}
/**
* 获取最新的条消息
*/
public MyMessage next() {
synchronized (this) {
if (list.size() > 0) {
if (position <= list.size() - 1) {
MyMessage message = list.get(position);
position++;
return message;
} else {
position = 0;
list.clear();
}
}
return null;
}
}
}