为什么我应该使用Android服务而不是Java线程

19
我对安卓服务和Java线程感到困惑,请帮助我理解应该在哪些情况下使用它们。根据我的理解:服务在后台运行,线程也一样。服务适用于网络操作或在后台播放MP3等活动,线程也是如此。那么它们之间的实际区别是什么,应该在何时使用它们?

1
我不确定你的问题是否仅限于Android,这通常涉及线程和进程之间的区别(我想象Android服务是由操作系统维护的单独进程,在您自己的进程处于非活动/被杀死/停止状态时...)。 - Ali
它是针对Android特定的。服务是应用程序的一个组件。这是Android的术语。Android应用程序的组件是非常特定的进程。服务更具体。在Android中,线程也是特定的,有些情况下无法使用它们(GUI)。 - Gangnus
7个回答

36

让我举个类比。

活动(Activities)和服务(Service)就像项目。

活动就像外部项目,这是客户(用户)所看到的。

服务就像内部项目。可能会有多个内部项目支持一个外部项目,也可能完全没有。

您可以“暂停”外部项目,但仍然可以继续支持它的内部项目。

主线程(Main Thread)就像公司老板

老板不应该因为太忙而被拖延,因为他不能迟到开会(UI冻结),否则客户(用户)会不满意。

线程(Threads)就像公司员工。

您拥有的员工越多,同时可以处理的事情就越多,前提是您有足够的设备(CPU速度)来支持它们。

多个员工可以同时在同一项目上工作,但老板应该只关注活动。


6
我认为主要的区别在于安卓系统的态度。服务是安卓基础架构的一部分,所以安卓将服务视为应用程序的工作部分,并考虑杀死服务作为最后的选择。此外,如果您的服务被杀掉(例如由于内存不足),您可以让系统自动重新启动它,只要有资源可用。此外,您可以调整服务优先级,使其与前台活动一样重要。至于线程,安卓不认为线程是必须保留的重要部分。因此,通常线程有更多机会最终被杀死。
例如,如果您有一个活动启动了一个工作线程,然后转到后台,由于安卓不认为线程是工作部分,它可能认为应用程序没有做任何事情,因为没有运行的活动或服务,并杀死整个应用程序,包括工作线程。
因此,当您启动一个服务时,您告诉系统类似这样的话:“嗨,我在这里处理一些业务,请不要在我完成之前杀死我。”,而安卓会注意到您的请求。

6

总体来说:一个应用程序的服务不仅可被该应用程序其他组件使用,还可被其他应用程序使用。

服务适用于程序中非GUI部分。

大多数情况下:服务比线程更加独立。服务比线程的生命周期更长。服务比线程更为复杂。

顺便提一句,线程并不仅仅在后台运行,它也可以在前台运行。


4

服务更类似于一个无头活动。

重要的一点是,服务是关于管理应用程序生命周期和在您的应用程序不在前台(没有UI可见)时保持工作运行能力的能力。它还提供了向其他应用程序公开功能的能力。

http://developer.android.com/reference/android/app/Service.html#WhatIsAService

通常,在启动服务时,您也会启动一个工作线程。在清单中有一些设置可以导致服务在新进程中启动,但通常您不需要这样做,因为它会使与您的服务通信更加困难。

当您需要从UI线程卸载工作而应用程序在前台时,请在Activity中使用一个普通线程,但是这项工作可以在您不再处于前台时停止。(可能会发生您的应用程序在不在前台时继续运行,但取决于许多因素)一般来说,Android可以在不在前台时杀死您的Activity,如果您的应用程序进程没有任何Activity或Service,则可以将其杀死。

使用带有线程的服务来执行在应用程序处于后台时进行的工作,并且您希望获得更好的寿命保证。

使用服务来向其他应用程序公开非UI功能。


2
根据Android开发者指南(http://developer.android.com/guide/components/services.html#Basics):
服务是一种组件,即使用户没有与您的应用程序交互,也可以在后台运行。因此,只有在需要时才应创建服务。
如果您需要在主线程之外执行工作,但仅在用户与您的应用程序交互时执行,请考虑创建一个新线程而不是服务。例如,如果要播放音乐,但仅在活动运行时播放,则可以在onCreate()中创建一个线程,在onStart()中开始运行它,然后在onStop()中停止它。还可以考虑使用AsyncTask或HandlerThread,而不是传统的Thread类。有关线程的更多信息,请参见进程和线程文档。
请记住,如果使用服务,默认情况下仍在应用程序的主线程中运行,因此如果执行密集或阻塞操作,仍应在服务内创建新线程。

2

Android中的Service默认情况下不会在单独的进程中运行,甚至不会在单独的线程中运行!它在应用程序的主线程(UI线程)中运行。因此,如果您想在Service中执行一些耗时的任务,请自己启动一个单独的线程,或使用IntentService


0

我们为什么需要服务是为了避免资源短缺。 例如,您在打开另一个应用程序后打开应用程序,因此在此时您的应用程序被添加到后台任务中。 在打开多个应用程序时,您的应用程序可能会被Android系统杀死。因此,如果您的应用程序具有服务,则不会被系统杀死,因为服务具有更高的优先级,即使它可能会杀死具有服务的应用程序,因此我们在onStartCommand()方法中使用常量返回类型。这就是START_STICKY,START_NOT_STICKYDELIVER_INTENT


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