个人学习_ Android异步消息处理机制
2016-08-06 15:28
302 查看
本文基于:
http://blog.csdn.net/guolin_blog/article/details/9991569
(不得不说,郭霖真大神@。@)
摘至:
http://blog.csdn.net/lmj623565791/article/details/47079737
1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。
2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。
3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue想关联。
4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。
5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法
子线程更新UI方法:
所以 平常 我们直接:
其他线程没有Looper.myLooper(),所以我们需要如下写:
示例代码:
handler.sendMessage(msg)
↓
queue.enqueueMessage(msg)
↓
queue.next()!=null;
出:
Looper.loop 一直循环
↓
if(queue.next()!=null) {handler.dispatchMessage(msg)}
↓
handler.handleMessage(msg);
http://blog.csdn.net/guolin_blog/article/details/9991569
(不得不说,郭霖真大神@。@)
摘至:
http://blog.csdn.net/lmj623565791/article/details/47079737
1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。
2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。
3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue想关联。
4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。
5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法
子线程更新UI方法:
Handler的post()方法
View的post()方法
Activity的runOnUiThread()方法
Handler的sendMessage()方法
由上文网址得知:
1、2、3的方法最后都是用handler的sendMessage方法的,所以下文根据网址总结下handler的处理过程。
[title2]前言[/title2]
Android UI线程是不安全,一般处理都是new Handler(),并在里面handleMessage可以在UI线程处理sendMessage发回来的信息。
[title2]注意点[/title2]
Handler是依附于创建时所在的线程
Handler()的实现需要一个Looper,(Looper里面有一个MessageQueue在不停循环)
一个线程只有一个Looper(原因详看下文Looper.prepare源码)、也就决定了一个线程只有一个Looper.
[title2]具体过程[/title2]
new Handler()源码(抄至上文网址):
public Handler() {
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 = null;
}
可见handler是依靠Looper.myLooper()不为null时起效。我们直接new Handler() 也没new 过Looper呀,怎么它自己就不为null生效了?
Looper.myLooper()源码:
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
所以(Looper)sThreadLocal.get()决定Handler的生死。
(Looper)sThreadLocal.get()的出生是Looper.prepare决定的。
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
现在总结:
Looper.prepare()→sThreadLocal.set()!=null→sThreadLocal.get()!=null→Looper.myLooper()!=null→new Handler()
一切的成功的基础是Looper.prepare()。那问题来了:Looper我们也没处理过啊。
其实首先,Android程序的运行入口点可以认为是android.app.ActivityThread类的main()方法;
然后main线程一建立就帮我们
Looper.prepareMainLooper(){prepare()}&&Looper.loop;
所以最后总结下
main线程handler的实现过程:
main()→Looper.prepareMainLooper()→Looper.prepare()→sThreadLocal.set()!=null→sThreadLocal.get()!=null→Looper.myLooper()!=null→new Handler()
其他线程用Handler的实现过程:
new Thread()→Looper.prepare()→...→new Handler()
总结:
main线程入口帮我们:Looper.prepareMainLooper(){Looper.myLooper()};
所以 平常 我们直接:
new Handler();
其他线程没有Looper.myLooper(),所以我们需要如下写:
new Thread() → Looper.prepare()→new Handler() →Looper.loop();
示例代码:
public class MainActivity extends Activity { private Handler handler1; private Handler handler2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler1 = new Handler(); new Thread(new Runnable() { @Override public void run() { Looper.prepare(); handler2 = new Handler(); Looper.loop(); } }).start(); } }
Handler的sendMessage()实现过程
进:handler.sendMessage(msg)
↓
queue.enqueueMessage(msg)
↓
queue.next()!=null;
出:
Looper.loop 一直循环
↓
if(queue.next()!=null) {handler.dispatchMessage(msg)}
↓
handler.handleMessage(msg);
相关文章推荐
- android异步消息处理机制 handler MessageQueue Looper 类 学习
- [学习总结]6、Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制学习笔记
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- 个人总结android消息处理机制:Looper,Handler,Message
- android异步消息处理机制
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android多线程----异步消息处理机制之Handler详解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android多线程及异步任务消息处理机制(一)--Handler的使用
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- Android学习札记28:深入理解Android中的消息处理机制——Thread、Looper、MessageQueue和Handler(2)
- 【转】Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系