【问题标题】:understanding Android Services and threads了解 Android 服务和线程
【发布时间】:2013-09-21 01:14:33
【问题描述】:

我对服务有疑问。

我知道服务在后台运行,但我认为您必须在服务中创建一个线程,否则它会阻塞主线程并且您会收到 ANR 错误。

我以为我明白了!但后来我在 Android 开发者指南中读到了这个:

...如果您的服务在用户与来自同一应用程序的活动交互时执行密集或阻塞操作,则服务将降低活动性能。为避免影响应用程序性能,您应该在服务内启动一个新线程。>

该段落提到“密集或阻塞操作”,但没有提到 ANR 错误,它提到了性能。那么服务是如何工作的呢?

假设一个活动启动一个服务。 Service是否默认在主线程的后台运行?这意味着您仍然可以在服务运行时使用您的活动,但是由于您的活动和服务共享主线程的资源,这会降低活动的性能,并且如果服务正在执行 CPU 密集型工作,它可能会离开没有资源可供活动使用,最终您会收到 ANR 错误。

最佳实践(但不一定,如果服务正在做轻量工作)是在服务中启动一个新线程,现在 Activity 和服务正在使用它们自己的线程资源。然后您可以关闭您的活动,但 Android 会保持服务线程处于活动状态。

是这样吗?谢谢=)

【问题讨论】:

  • 服务在唯一的主线程中运行。他们在后台什么都不做。在 Activity 处于活动状态时阻止服务将导致 ANR。

标签: android multithreading service


【解决方案1】:

我认为您必须在服务中创建一个线程,否则它会阻塞主线程并且您会收到 ANR 错误。

正确。

该段落提到了“密集或阻塞操作”,但没有提到 ANR 错误,而是提到了性能。

请随时在http://b.android.com 提交错误报告,让他们改进这部分文档。 :-)

Service是否默认在主线程后台运行?

Service 的生命周期方法,例如 onCreate()onStartCommand(),在主应用程序线程上调用。一些服务,比如IntentService,会为你提供一个后台线程(例如,onHandleIntent()),但这是特定于Service的特定子类的。

最终您会收到 ANR 错误。

是的。

最佳实践(但不一定,如果服务正在做轻量工作)是在服务中启动一个新线程,现在 Activity 和服务正在使用它们自己的线程资源。然后您可以关闭您的活动,但 Android 会保持服务线程处于活动状态。

基本上,是的。在这里,“轻工作”应该小于一毫秒左右。此外,您可能做的一些事情自然是异步的(例如,通过MediaPlayer 播放歌曲),所以Service 本身可能不需要自己的线程,因为它正在使用的其他东西正在做线程。

【讨论】:

  • 哦,我想我明白了。就像@zapl 你说的那样。默认情况下,服务在后台不做任何事情,回调在主线程上运行,如果服务工作时间超过 5 秒,你会得到一个 ANR。但是默认情况下不在后台运行的服务对我来说毫无意义。原因是您可以创建一个完全是 Service 的应用程序,然后它将拥有所有的主线程。
  • @ILovemyPoncho:“原因是您可以创建一个完全是服务的应用程序”——这并不实际。正如我在回答中指出的那样,服务有时会协调本身是异步的事物,因此我们不一定需要自己的线程。此外,某些服务可能有不同的线程需求——IntentService 只提供一个线程,但另一个服务可能需要一个线程池。因此,Service 将线程留给我们,让我们选择适合我们需求的东西,而不是强制使用特定的线程模型。
  • 哦,这比我想象的更有意义哈哈。这解决了我的疑惑。谢谢
猜你喜欢
  • 2014-08-11
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2017-05-15
  • 2016-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多