用AI赚第一桶💰低成本搭建一套AI赚钱工具,源码可二开。 广告
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来解决这个问题。