5.4.3 Looper和Handler的同步关系
最后更新于:2022-04-02 05:50:07
Looper和Handler会有什么同步关系呢?它们之间确实有同步关系,而且如果不注意此关系,定要铸成大错!
同步关系肯定和多线程有关,看下面的一个例子:
**例子2**
~~~
/先定义一个LooperThread类
class LooperThread extends Thread {
publicLooper myLooper = null;//定义一个public的成员myLooper,初值为空。
public void run() { //假设run在线程2中执行
Looper.prepare();
// myLooper必须在这个线程中赋值
myLooper = Looper.myLooper();
Looper.loop();
}
}
//下面这段代码在线程1中执行,并且会创建线程2
{
LooperThreadlpThread= new LooperThread;
lpThread.start();//start后会创建线程2
Looper looper = lpThread.myLooper;//<======注意
// thread2Handler和线程2的Looper挂上钩
Handler thread2Handler = new Handler(looper);
//sendMessage发送的消息将由线程2处理
threadHandler.sendMessage(...)
}
~~~
上面这段代码的目的很简单:
- 线程1中创建线程2,并且线程2通过Looper处理消息。
- 线程1中得到线程2的Looper,并且根据这个Looper创建一个Handler,这样发送给该Handler的消息将由线程2处理。
但很可惜,上面的代码是有问题的。如果我们熟悉多线程,就会发现标有“注意”的那行代码存在着严重问题。myLooper的创建是在线程2中,而looper的赋值则在线程1,很有可能此时线程2的run函数还没来得及给myLooper赋值,这样线程1中的looper将取到myLooper的初值,也就是looper等于null。另外,
~~~
Handler thread2Handler = new Handler(looper) 不能替换成
Handler thread2Handler = new Handler(Looper.myLooper())
~~~
这是因为,myLooper返回的是调用线程的Looper,即Thread1的Looper,而不是我们想要的Thread2的Looper。
对这个问题,可以采用同步的方式进行处理。你是不是有点迫不及待地想完善这个例子了?其实Android早就替我们想好了,它提供了一个HandlerThread来解决这个问题。
';