Android Service 翻译

本文详细介绍了Android Service的概念、生命周期、权限声明、进程管理以及如何创建本地和远程通讯Service的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android Service
=========================

public abstract class Service extends ContextWrapper implements ComponentCallbacks2


java.lang.Object
    |- android.content.Context
  |-    android.content.ContextWrapper
     |-     android.app.Service

已知的直接子类
AbstractInputMethodService, AccessibilityService, DreamService, IntentService, RecognitionService, RemoteViewsService, 

SpellCheckerService, TextToSpeechService, VpnService, WallpaperService


已知的间接子类
InputMethodService


类概览
=========================

Service是一个应用程序组件,用于一个应用程序需要长时间运行而不需要与用户交互的操作,或者为其它应用程序提供相应的服务功能。

每个Service类在其项目内的AndroidManifest.xml文件中都必须有一个对应的<service>声明。服务可以通过Context.startService()和

Context.bindService()启动。

需要注意的是,Service像其它应用程序对象一样,运行在其所属的主进程的主线程内。也就是说,如果你的Service需要对CPU进行密集型

请求(如播放MP3)或线程阻塞的操作(如网络连接),它会在其自己的线程去处理,更多信息请查看进程和线程的相关知识。

IntentService类可作为Service中的一个标准的执行类,在它的时间表内有它自己的线程完成相应的工作。

标题导读如下:
1. 什么是Service?
2. Service的生命周期
3. 相关的权限声明
4. 进程生命周期
5. 本地Service的样例
6. 远程通讯Service的样例
=========================

1. 什么是Service?
=========================
关于Service类最容易混肴的地方实际上是要弄清楚它不是什么:
- Service不是一个进程。Service对象本身并不意味着它是运行在自己的进程内;除非另外指定,否则它与应用运行在相同的进程中属于应

用的一部分。
- Service不是一个线程。这就意味着它不能工作在主线程内(这是为了避免应用没有响应导致错误)。

因此,服务本身其实是很简单的,提供两个主要特征:
- 一种是通过应用程序告诉系统它想要在后台做一些什么事情(即使用户不直接与应用程序交互)。这种情况适合调用 

Context.startService(), 要求系统根据Service的计划执行工作,一直运行到service或其他情况明确停止它。
- 一种是通过应用程序暴露其部分功能给其他应用程序。这种情况适合调用Context.bindService(), 它允许一个长期的连接使其与其它操

作进行交互。

当一个Service组件创建完成,其中一个原因,这一切其实是系统实例化组件并调用它的onCreate()以及主线程中其他的任何适当的回调。

它是由Service实现这些适当的行为,比如创建子线程完成它的工作。

请注意,由于服务本身就是这么简单,利用它你可以实现你想要的交互操作,简单的或复杂的:处理来至本地的Java对象你可以作出直接的

方法调用(如图所示Local Service Sample),提供一个可全远程的接口使用AIDL。

2. Service的生命周期
=========================
一个服务可以运行在系统中,有两个原因。如果有人调用Context.startService(),这时候系统会重新得到Service(创建它,如果需要会

调用它的onCreate()方法)并利用客户端提供的参数调用onStartCommand(Intent, int, int)方法。Service会从这个点开始运行,直到 

Context.stopService() 或者 stopSelf()被调用。请注意,多次调用Context.startService()不会叠加(虽然他们调用onStartCommand()

多做相应的结果),所以无论你调用了Context.startService()多少次,只要调用一次stopService()或stopSelf(),开启的Service将被停

止;不管怎样,服务可以使用他们的 stopSelf(int)方法去确保服务不停止直到开始的意图被处理。

对于开始的服务而言,有两个主要的操作模式,他们可以决定运行,根据他们的onStartCommand()的返回值:START_STICKY用于启动和停止

服务,明确需要,与此同时,START_NOT_STICKY 或者 START_REDELIVER_INTENT用于服务继续运行同时处理任何命令发送给他们。

客户也可以使用 Context.bindService() 持久连接到服务。这同样创建服务如果它没有运行(这样做的时候同时调用onCreate()),但是

不会调用onStartCommand()。客户端将收到从服务 onBind(Intent) 的方法返回的 IBinder 对象,这是允许客户端回调这个服务。只要已

建立连接这个服务会继续执行(无论客户端是否保留服务的 IBinder 的引用).通常返回的是一个复杂的IBinder接口,已经写在AIDL中。

一个服务可以开始并绑定到它的连接。比如,系统要保持服务运行要么是已开始的要么通过 Context.BIND_AUTO_CREATE 绑定一个或多个它

上面的。一旦这些情况无效,服务的onDestroy()方法被调用同时服务有效终止。当onDestroy()返回时,全部清理(停止线程,解除注册接

收器)应该是完成的。

3. 相关的权限声明
=========================
当它在清单中声明<service> 标签时全球访问的服务可以被执行时。通过这样做,其他应用程序需要在清单文件中声明一个相应的<uses-

permission> 才能够启动,停止,或绑定到服务。

从 GINGERBREAD 时起,当使用 Context.startService(Intent)时,你也可以设置 Intent.FLAG_GRANT_READ_URI_PERMISSION 和/或者 

Intent.FLAG_GRANT_WRITE_URI_PERMISSION 在 Intent 上。这将给予服务临时访问Intent中指定的URI。访问将持续到服务调用stopSelf(

int),启动命令或后一个,或直到服务已完全停止。本工程为授权其他应用程序访问的没有要求的权限保护的服务,甚至当服务所有都是

没有出口的。

此外,一个服务可以保护个人的IPC调用到它的权限,执行该呼叫前 通过调用实现 checkCallingPermission(String) 方法。

4. 进程生命周期
=========================
Android系统试图保持进程托管服务,只要服务已开始或有客户端已绑定到它。当运行时内存不足和需要杀死现有的进程,一个托管服务进

程的优先级在以下的可能性中变的更高:
- 如果该服务目前执行的代码在其 onCreate(), onStartCommand(), 或者 onDestroy() 方法中,这时宿主进程将是一个突显进程,确保此

代码可以执行不被杀的。
- 如果该服务已启动,那么服务进程比用户屏幕上可见的任何进程都次要,但要比任何不可见的进程更重要。因为一般只有少数的进程对用

户可见,这意味着服务不应该被杀死除了在极端低内存条件时。
- 如果有客户端绑定到服务,服务的主进程不会比客户端进程次要。就是说,如果一个客户端对用户是可见的,那么服务本身是可见的。
- 一个已开启的服务可以调用 startForeground(int, Notification) API 把服务放在前台的状态,系统会认为该服务是用户主动的,内存

不够时不会被杀死。(这仍然是理论上的,在极端的内存压力下,服务还是可能被杀死,但实际上这不应该过多担心。)

这意味着,大部分时间你的服务是正常运行的,它可以被系统杀死如果是在极端的内存压力下。如果发生这种情况,系统将尝试重新启动服

务。得出一个重要结果就是如果你实现了 onStartCommand()方法计划要做的工作是异步的或在另一个线程,这时你可以使用

START_FLAG_REDELIVERY 由系统为你提供一个Intent,这样就不会因为你的服务被杀死而不会重启服务。

其他应用组件和服务一样运行在同一进程中的(如Activity),当然,增加了所有进程的重要性超越了Service本身的重要性。

5. 本地Service的样例
=========================
参见Android SDK | docs。

6. 远程通讯Service的样例
=========================
参见Android SDK | docs。
本文转载自 上海Android培训机构青大实训王老师的博客,转载请注明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值