首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从异步线程访问UI线程

从异步线程访问UI线程
EN

Stack Overflow用户
提问于 2015-03-30 02:07:27
回答 2查看 1.4K关注 0票数 2

快速问题:我一直在使用生成工作线程来执行异步任务的框架,Retrofit就是一个很好的例子。在成功/失败部分,我可能会弹出一个对话框,该对话框需要位于UI线程上。在Retrofit的成功/失败部分中,我一直以这种方式访问底层活动/UI线程:

代码语言:javascript
复制
Dialog dialog = new Dialog(LoginActivity.this, R.style.ThemeDialogCustom);

这在99.9%的情况下都工作得很好,但偶尔在创建对话框时,我会收到以下错误:

代码语言:javascript
复制
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线程的最稳定的方法,还是我需要一种不同的方法?

EN

回答 2

Stack Overflow用户

发布于 2015-03-30 02:16:12

AFAIK,你使用的方法没有任何问题。出现问题的原因是,当工作线程完成时,当您尝试显示对话框时,活动的实例已经完成。因此,崩溃完全取决于线程完成所需的时间。似乎在您的情况下,线程主要在活动仍处于活动状态时结束;因此,在大多数情况下,您不会得到错误。

您需要做的是在尝试显示对话框之前检查活动是否仍在运行。最简单的方法之一是

代码语言:javascript
复制
if(!((Activity) LoginActivity.this).isFinishing())
{
    //safe to show your dialog
}
票数 0
EN

Stack Overflow用户

发布于 2015-03-30 02:41:24

如果您使用线程而不使用异步任务,请始终运行所有更改runOnUIThread中UI的内容,如下所示

代码语言:javascript
复制
activity.runOnUiThread(new Runnable() {
     @Override
     public void run() {
         //change UI
     }
});

更通用的方法是这样做,这几乎是相同的

代码语言:javascript
复制
new Handler(Looper.getMainLooper()).post(new Runnable() {
         @Override
         public void run() {
             //change UI
         }
    })

See here the minimal difference between runOnUIThread and MainLooper

如果要检查是否在主/UI线程上

代码语言:javascript
复制
if(Thread.currentThread() == Looper.getMainLooper().getThread()) {
   //you are on the main thread
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29332836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档