快速问题:我一直在使用生成工作线程来执行异步任务的框架,Retrofit就是一个很好的例子。在成功/失败部分,我可能会弹出一个对话框,该对话框需要位于UI线程上。在Retrofit的成功/失败部分中,我一直以这种方式访问底层活动/UI线程:
Dialog dialog = new Dialog(LoginActivity.this, R.style.ThemeDialogCustom);这在99.9%的情况下都工作得很好,但偶尔在创建对话框时,我会收到以下错误:
android.view.WindowManager$BadTokenException
LoginActivity.java line 343 in LoginActivity$6.success()
Unable to add window -- token android.os.BinderProxy@41662138 is not valid;
is your activity running?那么,我的方法是从工作线程访问活动上下文/UI线程的最稳定的方法,还是我需要一种不同的方法?
发布于 2015-03-30 02:16:12
AFAIK,你使用的方法没有任何问题。出现问题的原因是,当工作线程完成时,当您尝试显示对话框时,活动的实例已经完成。因此,崩溃完全取决于线程完成所需的时间。似乎在您的情况下,线程主要在活动仍处于活动状态时结束;因此,在大多数情况下,您不会得到错误。
您需要做的是在尝试显示对话框之前检查活动是否仍在运行。最简单的方法之一是
if(!((Activity) LoginActivity.this).isFinishing())
{
//safe to show your dialog
}发布于 2015-03-30 02:41:24
如果您使用线程而不使用异步任务,请始终运行所有更改runOnUIThread中UI的内容,如下所示
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//change UI
}
});更通用的方法是这样做,这几乎是相同的
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//change UI
}
})See here the minimal difference between runOnUIThread and MainLooper
如果要检查是否在主/UI线程上
if(Thread.currentThread() == Looper.getMainLooper().getThread()) {
//you are on the main thread
}https://stackoverflow.com/questions/29332836
复制相似问题