我试图在下面的代码段中发现我做错了什么,但我无法弄清楚,也无法在其他 StackOverflow 问题中找到答案。
运行下面的代码时,可运行块中的代码有时不会执行,这使我的应用程序挂起,直到向用户抛出 ANR。
private void initializeOnMainThread(final Context appContext) {
final Object syncLock = new Object();
Runnable runnable = new Runnable() {
@Override
public void run() {
// some init stuff
Log.d("CUSTOM_TAG", "STEP 3");
synchronized (syncLock) {
Log.d("CUSTOM_TAG", "STEP 4");
syncLock.notify();
Log.d("CUSTOM_TAG", "STEP 5");
}
}
};
if (Looper.myLooper() == Looper.getMainLooper()) {
runnable.run();
} else {
uiHandler.post(runnable);
Log.d("CUSTOM_TAG", "STEP 1");
try {
synchronized (syncLock) {
Log.d("CUSTOM_TAG", "STEP 2");
syncLock.wait();
Log.d("CUSTOM_TAG", "STEP 6");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
打印的日志如下:
D/CUSTOM_TAG:步骤 1
D/CUSTOM_TAG:步骤 2
初始化uiHandler
如下:
val uiHandler = new Handler(Looper.getMainLooper());
post
是整个代码中唯一调用uiHandler
的方法,没有调用过removeCallbacks
、removeMessage
或类似的东西。
为什么 Android 不执行 Runnable 块?
我不会说这真的是一个答案,但只要我无法弄清楚问题是什么,我就会为我遇到的问题发布解决方法。
解决方法包括将wait()
和notify()
换成CountDownLatch
类。
进行该更改后,该应用程序不再挂起(我可以说使用它增加了代码的可读性( - 双赢。