android---HandlerThread源码分析

      在上一篇我们分析了Handler的消息处理机制,我们也实现了在子线程中创建Handler对象,并且利用该Handler对象来处理了子线程自己发给自己的消息,但是要想让子线程中的Handler发挥作用,必须采用Looper.prepare( )来创建一个Looper对象,进而创建一个MessageQueue消息队列出来,随后调用Looper.loop( )方法来让消息队列运转起来;

     我们来回顾下上一篇的实例:

public class MainActivity extends Activity {
	public Handler mHandler;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		new Thread(new Runnable() {
			@Override
			public void run() {
				Looper.prepare();
				Handler handler = new Handler(){
					public void handleMessage(Message msg) {
						switch (msg.what) {
						case 0:
							System.out.println("message.what == 0");
							break;
						case 1:
							System.out.println("message.what == 1");
							break;
						default:
							break;
						}
					};
				};
				handler.sendEmptyMessage(0);
				Looper.loop();
			}
		}).start();
	}
}

输出结果:message.what == 0

      但是你不觉得很麻烦么?我们每次都要添加Looper.prepare( )和Looper.loop( )方法,这一点android已经为我们考虑到啦,就是HandlerThread;

我们先来看看HandlerThread的一个实例:

public class MainActivity extends Activity {
	public Handler mHandler;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		HandlerThread thread = new HandlerThread("huzhiwei");
		thread.start();
		Handler handler = new Handler(){

			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case 0:
					System.out.println("message.what == 0");
					break;
				case 1:
					System.out.println("message.what == 1");
					break;
				default:
					break;
				}
			}
		};
		handler.sendEmptyMessage(0);
	}
}

输出结果:message.what == 0

解释:

(1)首先通过构造函数生成一个HandlerThread对象,参数是用于调试用的,具体没多大用途

(2)调用start方法开启线程

(3)生成一个Handler对象,并重写里面的handleMessage方法

这下子你可能就会疑问为什么HandlerThread里面没有执行Looper.prepare()和Looper.loop()方法就能进行接收和处理消息呢?别急,其实是HandlerThread帮你封装了而已的,看看HandlerThread的源码就知道啦

class HandlerThread extends Thread {
    int mPriority;//线程优先级
    int mTid = -1;//线程ID
    Looper mLooper;//Looper对象

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;//如果创建HandlerThread的时候没有线程优先级传入,则定义为默认优先级
    }
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;//设置线程优先级
    }
    //这是监听方法,我们在创建HandlerThread的时候可以重写该方法,该方法会在run方法里面调用
    protected void onLooperPrepared() {
    }

    @Override
    public void run() {
        mTid = Process.myTid();//获取线程ID
        Looper.prepare();//生成Looper对象,同时创建MessageQueue消息队列,并且将Looper加入到ThreadLocal中
        synchronized (this) {
            mLooper = Looper.myLooper();//从ThreadLocal中获得Looper对象
            notifyAll();
        }
        Process.setThreadPriority(mPriority);//设置线程的优先级
        onLooperPrepared();//调用我们自己实现的回调方法
        Looper.loop();//开始消息处理
        mTid = -1;//将当前线程设置为invalid
    }
    public Looper getLooper() {
    	//如果当前线程不在ALIVE状态的话,直接返回null,说明我们没有执行start()方法
        if (!isAlive()) {
            return null;
        }
        
        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();//一直等待,直到mLooper不为null
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }
    
    public boolean quit() {
        Looper looper = getLooper();//获得当前的Looper对象
        if (looper != null) {
            looper.quit();//退出
            return true;
        }
        return false;
    }
}
        源码看注释就可以看懂了吧,这里有一个问题需要说明一下,在run方法里面有一个notifyAll()方法,getLooper方法里面有个wait()方法,这两个方法是相互匹配的,我们只有在run方法中创建了Looper对象才能在getLooper方法里面获取到该对象,如果run方法未创建的话,getLooper会执行wait方法一直等待, notifyAll会将原来在该对象上处于wait状态的线程全部结束其wait状态,因此wait和notifyAll是用来对生成Looper对象进行同步操作的;

你可能感兴趣的:(android,HandlerThread分析)