android 消息机制
2018-03-15 10:44
369 查看
android的消息机制,这肯定是被大家源码解析,分析坏了的一部分。首先这个消息机制用的比较频繁,主要用在子线程更新UI,再一个就是这个源码比较少,也是很好理解的,我感觉每个人都会来一篇消息机制的文章。
在这里就不进行MessageQueue和Looper的分析了,大家如果想看可以百度,或者自己去看下源码就都可以看懂的。我们接下来主要分析Handler处理消息的几种方式,以及他们在执行时的顺序。
我们都知道主线程是可以直接new Handler()的,而在子线程中却是不可以的,我们去看下这是为什么?
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}如果在子线程中会报这么一个错误,这是因为在子线程中没有Looper对象。如果子线程也想创建Handler,可以去参考HandlerThread这个类的实现。为什么主线程是可以的,那就要去找一个ActivityThread的类了,这是在应用启动的时候开启的一个线程也是传说中的UI线程或主线程,源码:
public static void main(String[] args) {
...
//这个地方就是创建一个Looper,并且放在ThreadLocal里。下面会有源码
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);
// Loop.loop()是一个死循环,但是在没有消息的时候会堵塞
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
return sThreadLocal.get();
}这个地方用到了ThreadLocal,大家可以自己去自行百度。好了这个地方已经解释了UI线程里面可以new Handler的原因。下面就是我们要解释Handler出来消息的几种方式。
在这我就默认大家都是知道Message在处理的时候是调用msg.target.dispatchMessage()方法来处理,这个msg.target就是我们Handler。下面我们来看下这个dispatchMessage方法
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
// 处理消息的第一种方式
handleCallback(msg);
} else {
if (mCallback != null) {
// 处理消息的第二种方式
if (mCallback.handleMessage(msg)) {
return;
}
}
// 处理消息的第三种方式
handleMessage(msg);
}
}在这里可以看出处理消息有三种方式,并且彼此不会重叠,都是执行一次。
第一种方式:
private static void handleCallback(Message message) {
message.callback.run();
}这个地方message.callback是什么地方给的呢?
{
return sendMessageDelayed(getPostMessage(r), 0);
}private static Message getPostMessage(Runnable r) {
//这个地方就是把Runnable赋值给Message的callback了,也就有我们上面代码的调用了
Message m = Message.obtain();
m.callback = r;
return m;
}第二种方式:Handler为了防止在创建是都要写一个子类,所以提供了一个接口,也就是Handler.Callback
第三种方式:调用handleMessage方法
Handler的创建方式:
Handler handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
}
};就会调用我们写的handleMessage方法,进行处理Message。
Android消息机制概述
说到Android的消息机制,大家肯定会想到Handler。是的,Android的消息机制主要是指Handler的运行机制以及Handler所附带的MessageQueue和Looper的工作过程。当我们工作的时候我们只要接触到Handler就可以了。为什么要有Android消息机制?
我们知道Handler的主要作用是将一个任务切换到某个指定的线程去执行,比如Android规定访问UI只能在主线程中进行,如果在子线程中访问那么程序会抛异常,如下所示:void checkThread(){ if(mThread != Thread.currentThread()){ throw new CalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); } }为什么系统不允许在子线程中访问UI呢?这是因为Android的UI控件不是线程安全的,如果在多线程中访问UI控件则会导致不可预期的状态。那为什么不对UI控件访问加锁呢?缺点有两个:首先加锁会让UI控件的访问的逻辑变的复杂;其次,锁机制会降低UI的访问效率。那我们不用线程来操作不就行了吗?但这是不可能的,因为Android的主线程不能执行耗时操作,否则会出现ANR。所以,从各方面来说,Android消息机制是为了解决在子线程中无法访问UI的矛盾。
在这里就不进行MessageQueue和Looper的分析了,大家如果想看可以百度,或者自己去看下源码就都可以看懂的。我们接下来主要分析Handler处理消息的几种方式,以及他们在执行时的顺序。
我们都知道主线程是可以直接new Handler()的,而在子线程中却是不可以的,我们去看下这是为什么?
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}如果在子线程中会报这么一个错误,这是因为在子线程中没有Looper对象。如果子线程也想创建Handler,可以去参考HandlerThread这个类的实现。为什么主线程是可以的,那就要去找一个ActivityThread的类了,这是在应用启动的时候开启的一个线程也是传说中的UI线程或主线程,源码:
public static void main(String[] args) {
...
//这个地方就是创建一个Looper,并且放在ThreadLocal里。下面会有源码
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);
// Loop.loop()是一个死循环,但是在没有消息的时候会堵塞
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
public static void prepareMainLooper() { // 这里就是创建Looper的方法 prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } // 这个地方就是把在prepare(false)中存入的Looper取出来 sMainLooper = myLooper(); } }
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } //创建一个Looper放到ThreadLocal里面 sThreadLocal.set(new Looper(quitAllowed)); }public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}这个地方用到了ThreadLocal,大家可以自己去自行百度。好了这个地方已经解释了UI线程里面可以new Handler的原因。下面就是我们要解释Handler出来消息的几种方式。
在这我就默认大家都是知道Message在处理的时候是调用msg.target.dispatchMessage()方法来处理,这个msg.target就是我们Handler。下面我们来看下这个dispatchMessage方法
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
// 处理消息的第一种方式
handleCallback(msg);
} else {
if (mCallback != null) {
// 处理消息的第二种方式
if (mCallback.handleMessage(msg)) {
return;
}
}
// 处理消息的第三种方式
handleMessage(msg);
}
}在这里可以看出处理消息有三种方式,并且彼此不会重叠,都是执行一次。
第一种方式:
private static void handleCallback(Message message) {
message.callback.run();
}这个地方message.callback是什么地方给的呢?
handler.post(new Runnable() { @Override public void run() { } });public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}private static Message getPostMessage(Runnable r) {
//这个地方就是把Runnable赋值给Message的callback了,也就有我们上面代码的调用了
Message m = Message.obtain();
m.callback = r;
return m;
}第二种方式:Handler为了防止在创建是都要写一个子类,所以提供了一个接口,也就是Handler.Callback
public interface Callback { public boolean handleMessage(Message msg); }Handler的创建方式:
Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { return false; } });这种方式处理完Message不要忘记返回true。
第三种方式:调用handleMessage方法
Handler的创建方式:
Handler handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
}
};就会调用我们写的handleMessage方法,进行处理Message。
相关文章推荐
- Android消息机制_概念
- android 消息机制浅析
- 深入解析android 消息机制
- Handler,Message,Looper,MessageQueue 解析 -Android 异步消息机制
- (转)Android 消息机制学习
- Android消息机制(2)
- 深入剖析Android消息机制
- 图解 Android Handler 线程消息机制
- Android Handler 消息机制
- 我的Android读书笔记——(3)Android消息机制
- Android 消息机制Handler
- Android 消息机制
- Android消息机制–Handler
- Android 消息机制 - Message
- Android 消息机制
- 【Android学习】消息机制Handler
- Android 消息机制(Handler,Looper,MessageQueue,Message)
- Android Handler AsyncTask 消息机制
- 图片理解Android消息机制
- Study on Android【六】--消息机制,异步和多线程