您的位置:首页 > 移动开发 > Android开发

个人学习_ 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方法:

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  异步 线程
相关文章推荐