如何判断代码是不是需要在 UI 线程上运行

Posted

技术标签:

【中文标题】如何判断代码是不是需要在 UI 线程上运行【英文标题】:How to tell if code needs to be run on the UI thread如何判断代码是否需要在 UI 线程上运行 【发布时间】:2018-09-13 23:48:34 【问题描述】:

我在我的应用程序中使用了工作线程,因此了解哪些代码可以从工作线程运行以及哪些代码需要在 UI 线程上运行对我来说至关重要。

android 文档中,可以找到以下提示:

因此,您不得从工作线程操作您的 UI — 您必须这样做 从 UI 线程对用户界面的所有操作。 [...] 但是,请注意,您不能从任何线程更新 UI,除了 UI 线程或“主”线程。

(source)

但“操作用户界面”在实践中的含义通常并不像看起来那么清楚。当然,很明显,您不能从工作线程中隐藏视图、操作按钮文本、添加列表视图条目等。

但是,例如,从工作线程调用setRequestedOrientation() 怎么样?这是允许的还是它属于 UI 操作,因此必须从 UI 线程调用?有什么方法可以告诉我或者我应该保持安全并在有疑问时更好地在 UI 线程上运行代码?

【问题讨论】:

"有什么办法可以告诉"——如果你从后台线程调用它并且你崩溃了一个异常,表明你不能从后台线程调用它,那么你需要使用 main应用程序线程。在某些情况下,您可能会在编译时收到有关该问题的 Lint 警告/错误。 setRequestedOrientation() 在后台线程中工作正常。那么这是否意味着它可以从后台线程调用它,或者它只是纯粹的运气,下次它可能会崩溃? AFAIK,行为应该是一致的。如果框架不抱怨你使用的线程,那么框架的工作就是确保线程安全。但是,结果可能会因操作系统版本或制造商的调整而异。如果您真的厌恶风险,请在主应用程序线程上进行工作。 【参考方案1】:

一般来说,您应该从 API 文档中获取指导​​。例如Activity.onCreate() 明确指出:

此方法必须从应用的主线程调用。

对于您给Activity.setRequestedOrientation() 的示例,没有明确声明应在特定线程上调用该方法。通常,如果关注线程,文档会说明这一点。

如果您更喜欢确定性,那么您也致电Activity.runOnUiThread()

【讨论】:

以上是关于如何判断代码是不是需要在 UI 线程上运行的主要内容,如果未能解决你的问题,请参考以下文章

这些在 UI 线程上运行代码的方法有啥区别?

异步代码是不是在 UI 线程或新/不同线程中运行以不阻塞 UI?

我们是不是需要在主线程或主队列中更新 UI?

ContentProvider insert() 总是在 UI 线程上运行?

Java如何判断线程池所有任务是不是执行完毕

如何仅在一个线程上运行任务? [复制]