android 特有的线程,消息同步:
private void testWait(){
HandlerThread ht = new HandlerThread(“Camera Handler Thread”);
ht.start();//自带Looper 的线程 looper 循环检查消息队列有没有消息,
mCameraHandler = new CameraHandler(ht.getLooper()); //
有: 取出来 msg.target.dispatchMessage(msg); target 既是handler 发到对应消息的handler ,执行handleMessage操作 即在HandlerThread 所在线程上执行。
Handler的构造函数中可以看到,最终会把前面生成的Looper对象和MessageQueue对象都保存起来,赋值给自己的成员变量。
至此,Handler、Looper以及MessageQueue就全部联系起来了
/
public Handler(Callback callback, boolean async) {
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;//重要 ,看这里,之前把HandlerThread 的looper 给了handler过来,因此,handler 发消息的消息队列也就是与HandlerThread 的消息队列共用一个。
mCallback = callback;
mAsynchronous = async;
}
public Looper getLooper() {
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();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
mCameraHandler.obtainMessage(OPEN_CAMERA, 1, 0).sendToTarget();// 发消息到HandlerThread
boolean ret = false;
ret = mCameraHandler.waitDone();
Log.v(TAG, "ret = " + ret);
}
private class CameraHandler extends Handler {
CameraHandler(Looper looper) {
super(looper);
}
/*
* Waits for all the {@code Message} and {@code Runnable} currently in the queue
* are processed.
*
* @return {@code false} if the wait was interrupted, {@code true} otherwise.
*/
public boolean waitDone() {
final Object waitDoneLock = new Object();
final Runnable unlockRunnable = new Runnable() {
@Override
public void run() {
synchronized (waitDoneLock) {//这个线程的运行所在的消息需要等待上一个消息处理完才会走。
Log.v(TAG, " notifyAll start");
waitDoneLock.notifyAll();
}
}
};
synchronized (waitDoneLock) {
mCameraHandler.post(unlockRunnable);//发个消息就返回了
try {
Log.v(TAG, “start wait”);
waitDoneLock.wait();//等待,如此,OPEN_CAMERA 处理完了 走到下一个消息,这个地方就被唤醒。
} catch (InterruptedException ex) {
Log.v(TAG, “waitDone interrupted”);
return false;
}
}
return true;
}
/**
* This method does not deal with the API level check. Everyone should
* check first for supported operations before sending message to this handler.
*/
@Override
public void handleMessage(final Message msg) {
switch (msg.what) {
case OPEN_CAMERA:
try {
Log.v(TAG, "start sleep 4s");
Thread.sleep(4000);
Log.v(TAG, "end sleep 4s");
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
default:
}
}
两个线程互发消息
// 发送信息的线程类
class MySendThread extends Thread{
public void run(){
int i=0;
while(i!=10){
Bundle bundle=new Bundle();
bundle.putString("num","第"+i+"次");//bundle中也可以放序列化或包裹化的类对象数据
msg=handler.obtainMessage();//每发送一次都要重新获取
msg.setData(bundle);
handler.sendMessage(msg);//用handler向主线程发送信息 handler **在主线程创建的。**
msg=handler2.obtainMessage();
msg.what=i;
handler2.sendMessage(msg);//用handler2向myAcceptThread线程发送信息
//休眠3秒,需要异常处理
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
}
//接收信息的线程类
class MyAcceptThread extends Thread{
public void run(){
Looper.prepare();//准备Looper对象
//在分线程中实现handler2,就会在分线程中处理其msg,因此 在AMS中new Handler 通常是需要自带参数的:
例如:mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper()); 这样消息才能发到指定的线程, 并由指定的线程处理消息。
handler2=new Handler(){//这是用匿名内部类生成一个handler对象
public void handleMessage(Message msg) {
proBar.setProgress(msg.what);
}
};
//调用Looper的loop方法后,Looper对象将不断从消息队列中取出消息对象并交给handleMessage处理
//没有消息时该线程会阻塞
Looper.loop();
}
}