在Android开发中,Looper类是与线程以及消息处理紧密相关的一个类。它管理着一个消息队列(MessageQueue),允许你发送和处理Message和Runnable对象。Looper.prepare()和Looper.loop()是Looper类中两个非常重要的方法,它们的作用分别如下:
- Looper.prepare()
Looper.prepare()方法用于在当前线程中初始化一个Looper对象,并为该线程创建一个消息队列(如果尚未创建的话)。这个方法通常被调用在线程的run()方法开始处,以表明这个线程将是一个Looper线程,即这个线程将运行一个消息循环,用于接收和处理消息和Runnable对象。
需要注意的是,Looper.prepare()在一个线程中只能被调用一次,因为每个线程只能有一个Looper和一个消息队列。
- Looper.loop()
Looper.loop()方法会启动Looper的事件循环。一旦调用此方法,当前线程就会进入一个无限循环,不断地从消息队列中取出消息(Message)或Runnable对象,并分发它们给相应的Handler进行处理。这个过程会一直持续下去,直到调用Looper.quit()或Looper.quitSafely()方法来停止Looper的循环。
典型用法
在Android中,UI线程(主线程)默认已经有一个Looper在运行,因此不需要在UI线程中显式调用Looper.prepare()和Looper.loop()。但是,如果需要在一个新!的!线!程!中处理消息,你就需要手动调用这两个方法。以下是一个简单的示例:
public class MyThread extends Thread {
private Handler handler;
@Override
public void run() {
Looper.prepare(); // 初始化Looper和消息队列
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 处理消息
// 你可以在这里执行后台任务或者更新UI(如果这是主线程的Handler)
}
};
Looper.loop(); // 启动消息循环
}
// 提供一个公共方法来获取Handler
public Handler getHandler() {
return handler;
}
}
// 在其他线程中发送消息
public class OtherThread extends Thread {
private MyThread myThread;
public OtherThread(MyThread myThread) {
this.myThread = myThread;
}
@Override
public void run() {
// 确保myThread已经启动并且Looper已经准备好
if (myThread.isAlive() && myThread.getHandler() != null) {
Handler handler = myThread.getHandler();
// 发送消息
handler.sendEmptyMessage(0); // 发送一个空消息,消息码为0
// 或者创建一个Message对象并发送它
Message message = Message.obtain();
message.what = 1; // 设置消息码为1
handler.sendMessage(message); // 发送消息
}
}
}
// 在主线程或其他地方创建和启动线程
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyThread myThread = new MyThread();
myThread.start();
OtherThread otherThread = new OtherThread(myThread);
otherThread.start();
}
}
在这个例子中,MyThread类重写了run()方法,并在其中调用了Looper.prepare()来初始化Looper和消息队列,然后创建了一个Handler用于处理消息。最后,通过调用Looper.loop()来启动消息循环,这样该线程就能够接收和处理消息了。
在其他线程中,需要确保在发送消息之前MyThread的Looper已经准备好
如果先发送消息到handler,然后再启动Looper.loop(),那么消息不会被立即处理。Handler是用于发送和处理Message或Runnable对象的,它依赖于Looper来管理消息队列。在调用Looper.loop()之前,消息队列并没有被启动,因此发送到handler的消息会停留在队列中,等待Looper开始循环后才会被处理。
要正确处理消息,你需要先调用Looper.prepare()来初始化Looper和消息队列,然后启动Looper.loop()来开始消息循环,最后再通过handler发送消息。这样,发送的消息才会被Looper捕获并分发给handler进行处理。
总结一下,正确的顺序应该是:
调用Looper.prepare()来准备Looper和消息队列。
创建handler并将其与Looper关联。
调用Looper.loop()来启动消息循环。
通过handler发送消息。