如果处理程序在 Looper.prepare() 之后但在 Looper.loop() 被调用之前向线程发布消息,会发生什么情况?
What happens if a Handler posts a message to a thread after Looper.prepare() but before Looper.loop() has been called?
考虑以下片段:
Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
getLooper().quitSafely();
}
};
for(int i = 0; i < urls.size(); i++) {
useCaseProvider.get().execute(callback, handler, urls.get(i), threadPool);
}
Looper.loop();
//Continue processing the results of all the use cases after the
//loop has been asked to terminated via the handler
一点背景知识:我正在 UI 线程上做一些处理,我需要在其中对大量设备执行 ping 操作并对结果进行处理。我需要并行执行请求以提高效率。
问题:如果这些用例中的一个以某种方式执行得足够快并在我能够点击 Looper.loop() 之前进行回调;消息会排队还是丢失?处理程序将可运行对象发布到原始线程,回调将被发布回该线程。
假设您在 useCaseProvider 交付结果之前调用了 Looper.prepare(),您应该没问题。
如果未调用 Looper.prepare,您应该会看到抛出 RuntimeException。
Looper 对象绑定到托管消息队列的本地线程。 Looper.prepare 函数将构建此消息队列,此时您可以开始对消息进行排队。一旦你触发 Looper.loop() 那些未决消息将开始执行。
看着这个片段,我不太确定事情是如何联系在一起的。
通常你想像这样构造一个循环器:
private static final class MyThread extends Thread {
private Handler mHandler;
@Override
public void run() {
Looper.prepare();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// handle message
}
};
Looper.loop();
}
public Handler getHandler() {
return mHandler;
}
}
我假设您的线程池是一个 MyThread 线程池,每个线程都有自己的 Looper。线程池应该初始化你的线程,所以一旦你交付一个 Runnable 由你的线程执行,运行() 方法应该初始化 Looper。
另一方面,如果您希望将您的 Handler 与特定的循环器相关联(即,您没有像上面那样在线程中构建处理程序),那么您应该将 Looper 线程传递给构造函数,例如:
Handler h = new Handler(myLooperThread);
如果您不指定,则处理程序会使用创建它的线程从 ThreadLocal 对象中获取该线程的 Looper。
最后,如果您打算在与 UI 线程关联的处理程序上传递消息,那么您不必担心调用 Looper.prepare 或 Looper.loop。这是由 Activity.
处理的
考虑以下片段:
Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
getLooper().quitSafely();
}
};
for(int i = 0; i < urls.size(); i++) {
useCaseProvider.get().execute(callback, handler, urls.get(i), threadPool);
}
Looper.loop();
//Continue processing the results of all the use cases after the
//loop has been asked to terminated via the handler
一点背景知识:我正在 UI 线程上做一些处理,我需要在其中对大量设备执行 ping 操作并对结果进行处理。我需要并行执行请求以提高效率。
问题:如果这些用例中的一个以某种方式执行得足够快并在我能够点击 Looper.loop() 之前进行回调;消息会排队还是丢失?处理程序将可运行对象发布到原始线程,回调将被发布回该线程。
假设您在 useCaseProvider 交付结果之前调用了 Looper.prepare(),您应该没问题。 如果未调用 Looper.prepare,您应该会看到抛出 RuntimeException。
Looper 对象绑定到托管消息队列的本地线程。 Looper.prepare 函数将构建此消息队列,此时您可以开始对消息进行排队。一旦你触发 Looper.loop() 那些未决消息将开始执行。
看着这个片段,我不太确定事情是如何联系在一起的。 通常你想像这样构造一个循环器:
private static final class MyThread extends Thread {
private Handler mHandler;
@Override
public void run() {
Looper.prepare();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// handle message
}
};
Looper.loop();
}
public Handler getHandler() {
return mHandler;
}
}
我假设您的线程池是一个 MyThread 线程池,每个线程都有自己的 Looper。线程池应该初始化你的线程,所以一旦你交付一个 Runnable 由你的线程执行,运行() 方法应该初始化 Looper。
另一方面,如果您希望将您的 Handler 与特定的循环器相关联(即,您没有像上面那样在线程中构建处理程序),那么您应该将 Looper 线程传递给构造函数,例如:
Handler h = new Handler(myLooperThread);
如果您不指定,则处理程序会使用创建它的线程从 ThreadLocal 对象中获取该线程的 Looper。
最后,如果您打算在与 UI 线程关联的处理程序上传递消息,那么您不必担心调用 Looper.prepare 或 Looper.loop。这是由 Activity.
处理的