Activity和Service是否在同一个线程中运行?

3
我对Handler、Service和Activity的基本概念有些困惑。我在很多地方看到提到“Service在UI线程中运行”。对于这个说法,我有几个问题:
  • 上述说法是真还是假?
  • 有人可以从Android Service参考文献中解释这个说法吗?

Service不是一个线程。它本身不是用于在主线程之外执行工作(为了避免应用程序无响应的错误)。

  • 如果Service在UI线程中运行,那么它不适合进行重量级的工作。是真还是假?
  • 如果没有正在运行的Activity,那么Service将在哪个线程中运行?如果上述说法是真的。
  • 如果上述说法是真的,那么如果我在Service和Activity中声明Handler会发生什么?因为单个线程只能有一个Handler实例。
  • 如果问题太初级,请原谅。


    1
    概念验证:启动一个活动,并从其onCreate方法中启动一个服务,在服务的onStartCommand中调用SystemClock.sleep(10000);观察到在服务中进行睡眠时,活动无法继续进行。 - Kevin Lee
    2个回答

    5
    上述的说法是真还是假?
    在Java中,没有任何对象在线程上"运行",方法才在线程上运行。
    因此,更加准确的说法是,Service的生命周期方法-- onCreate(), onStartCommand(), onBind()和onDestroy() --在主应用程序线程上调用。
    能有人解释一下这个来自Android Service参考的语句吗?
    我不知道怎样比它写得更好。尽管Service可以管理后台线程,但Service本身并不是线程。
    如果Service在UI线程中运行,那么它不适合进行繁重的工作?
    在Java中,没有任何对象在线程上"运行",方法才在线程上运行。
    因此,更加准确的说法是,您不应该直接触发上述生命周期方法引起耗时工作。
    如果没有Activity在运行,那么Service将在哪个线程上运行?
    在Java中,没有任何对象在线程上"运行",方法才在线程上运行。
    无论前台是否有Activity甚至是否存在Activity,都会在主应用程序线程上调用上述的生命周期方法。
    那么,如果我在Service和Activity中都声明了Handler,会发生什么?
    您将拥有一个Handler实例。
    Handler的默认行为是将其绑定到主应用程序线程,无论您是在Activity还是Service中创建Handler。

    如果我的服务启动一个线程,并且我想要一个类似这样的通信通道:线程可以向服务发送数据,服务也可以向活动发送数据。如果服务和活动处理程序与应用程序处理程序绑定在一起,那么如果线程向服务发送消息,哪个处理程序将接收到该消息? - Kanwar Saad
    @KanwarSaad:这条消息将发送到您调用sendMessage()Handler - CommonsWare
    它不起作用...所以我做的是在活动和服务中都创建了一个处理程序。将服务处理程序传递给新线程。然后,线程使用该处理程序向服务发送消息。我将接收到的消息复制到另一个消息中,然后使用UI处理程序将其发送到UI。这会导致androidruntimeexception:此消息已在使用中。 - Kanwar Saad
    @KanwarSaad:那么也许您应该考虑其他组件间通信的技术,例如使用startService()向服务发送命令,或使用LocalBroadcastManager,或使用第三方事件总线,如Otto。无论如何,您当前的问题与您最初的问题无关。如果您想让别人帮助您调试Handler的使用,请在新的StackOverflow问题中提问,包括您正在使用的代码和显示异常的堆栈跟踪。 - CommonsWare
    谢谢,我会将这个答案标记为正确的,因为它回答了我大部分的问题。 - Kanwar Saad

    1

    来自官方文档:

    服务运行在其所在进程的主线程中-服务不会创建自己的线程,也不会在单独的进程中运行(除非您另有指定)。这意味着,如果您的服务将执行任何CPU密集型操作或阻塞操作(例如MP3播放或网络),则应在服务内部创建一个新线程来执行该操作。通过使用单独的线程,您将减少发生“应用程序无响应”(ANR)错误的风险,并且应用程序的主线程可以保持专用于与您的活动进行用户交互。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接