【Android个人理解(一)】通过Looper与Handle的关系,理解Loope

Looper与Handle是Android独有的新概念,但我们学习中常常将他们分开学习,实际上两者密不可分。 Looper与Handle的关系: Looper是负责在线程里建立消息循环的类,,包括准备,开始循环,停止等整个消息循环的生命周期。Handle是负责不同线程之间消息的类,包括消息的发送,接受,清除等消息的生命周期。 但是只有存在Looper的线程,才会用到Handle。没有Handle,Looper无法接收消息,也就无法实现功能。 我们通过Looper与Handle的源码来分析: Looper.java

private static final ThreadLocal sThreadLocal = new ThreadLocal();() {if (sThreadLocal.get() != null) {throw new RuntimeException(“Only one Looper may be created per thread”);}sThreadLocal.set(new Looper());}

这里说明通过prepare()创建Looper对象。同时Android也规定一个线程只能有一个Looper。 由上new Looper(),我们看 Looper的构造方法。

final MessageQueue mQueue; private Looper() {mQueue = new MessageQueue();mRun = true;mThread = Thread.currentThread();}

可以看到在Looper的构造函数中,创建了一个消息队列对象mQueue,此时,调用Looper. prepare()的线程就建立起一个消息循环的对象。

再开始看Handle的源码: Handle.java

final MessageQueue mQueue;final Looper mLooper;public Handler() {if (FIND_POTENTIAL_LEAKS) {> 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;}

倒数第五行”Can’t create handler inside thread that has not called Looper.prepare()” 说明Handle的使用必须存在 Looper.prepare(),即必须存在信息队列,这样Handle才能找到信息。Handler通过mLooper = Looper.myLooper()绑定到线程的局部变量Looper上去,同时Handler通过mQueue =mLooper.mQueue获得线程的消息队列。

而没有Handle处理信息即handleMessage (Message msg){},只有Looper的信息队列在循环,信息就没有价值,用武之地。

而我们平时用Handle时,只是在UI线程中却没有声明Looper,是因为UI线程本身默认含有Looper机制。这个我们程序报错时经常看到“looper”。

最后总结工作原理: 1、 初始化Looper,启动消息循环。

2、 绑定handler到CustomThread实例的Looper对象

3、 在Looper循环中,通过Handle发送或一直等待消息。

4、 Handle通过Looper得到消息,处理消息。

附代码实例和更多Looper实现机制源码:

package com.zhuozhuo;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;{MSG_HELLO = 0;private Handler mHandler;(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);new CustomThread().start();//新建并启动CustomThread实例 findViewById(R.id.send_btn).setOnClickListener(new OnClickListener() {(View v) {//点击界面时发送消息 String str = “hello”;Log.d(“Test”, “MainThread is ready to send msg:” + str);mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();//发送消息到CustomThread实例 }});}class CustomThread extends Thread {() {//建立消息循环的步骤 Looper.prepare();//1、初始化Looper mHandler = (Message msg) {//3、定义处理消息的方法 switch(msg.what) {case MSG_HELLO:Log.d(“Test”, “CustomThread receive msg:” + (String) msg.obj);}}};Looper.loop();//4、启动消息循环 }}}

Google源码:

{private final Object mLock = new Object();private Looper mLooper;/*** Creates a worker thread with the given name. The thread* then runs a {@link android.os.Looper}.* @param name A name for the new thread*/Worker(String name) {Thread t = new Thread(null, this, name);t.setPriority(Thread.MIN_PRIORITY);t.start();synchronized (mLock) {while (mLooper == null) {try {mLock.wait();} catch (InterruptedException ex) {}}}}public Looper getLooper() {return mLooper;}() {synchronized (mLock) {Looper.prepare();mLooper = Looper.myLooper();mLock.notifyAll();}Looper.loop();}() {mLooper.quit();}}

走走停停,不要害怕错过什么,

【Android个人理解(一)】通过Looper与Handle的关系,理解Loope

相关文章:

你感兴趣的文章:

标签云: