用户登录
用户注册

分享至

Android Service回调和配置

  • 作者: 浮生若梦
  • 来源: 51数据库
  • 2021-08-24

Service 生命周期方法回调

创建服务,必须创建 Service 的子类(或使用它的一个现有子类)。可以重写一些回调方法,从而处理服务生命周期的某些关键方面,主要的回调方法有 onCreate()onBind()onRebind()onStartCommand()onStart()onUnbind()onDestroy()

onCreate()

首次创建服务时,系统会(在调用 onStartCommand()onBind() 之前)调用此方法来执行一次性设置程序。如果服务已在运行,则不会调用此方法。

onBind()

当另一个组件想要与服务绑定时,系统会通过调用 bindService() 来调用此方法。在此方法的实现中,必须通过返回 IBinder 提供一个接口,以供客户端用来与服务进行通信。但是,如果并不希望服务允许绑定,则应返回 null。

onRebind()

服务未被销毁,再次绑定时回调。前提是 onUnbind() 方法返回true(如果服务已启动并接受绑定,则当系统调用 onUnbind() 方法时,如果想在客户端下一次绑定到服务时接收 onRebind() 调用,则可选择返回 true)。onRebind() 返回空值,但客户端仍在其 onServiceConnected() 回调中接收 IBinder。

onStartCommand()

当另一个组件(如 Activity)请求启动服务时,系统会通过调用 startService() 来调用此方法。执行此方法时,服务即会启动并可在后台无限期运行。如果实现此方法,则在服务工作完成后,需负责通过调用 stopSelf()stopService() 来停止服务。(如果只想提供绑定,则无需实现此方法)。

onStart()

该方法已过时,使用 onStartCommand() 回调即可。

onUnbind()

当所有客户端都和服务解除绑定时调用。解除绑定方法 context.unbindService()

onDestroy()

当不再使用服务且准备将其销毁时,系统会调用此方法。服务应通过实现此方法来清理资源,如线程、注册的监听器、接收器等。这是服务接收的最后一个调用。

Service 生命周期流程图

服务生命周期图

左图显示使用 startService() 创建的服务的生命周期,右图显示使用 bindService() 创建的服务的生命周期

  • 服务的整个生命周期贯穿调用 onCreate() 和返回 onDestroy() 之间的这段时间。与 Activity 类似,服务也在 onCreate() 中完成初始设置,并在 onDestroy() 中释放所有剩余资源。
  • 服务的活动生命周期从调用 onStartCommand()onBind() 开始。每种方法均会获得 Intent 对象,该对象由 startService()bindService() 方法传递。
  • 对于启动服务,活动生命周期与整个生命周期会同时结束(即便是在 onStartCommand() 返回之后,服务仍然处于活动状态)。对于绑定服务,活动生命周期会在 onUnbind() 返回时结束。
  • 尽管可以通过调用 stopSelf()stopService() 来停止绑定服务,但该服务并没有相应的回调(如 onStop() 回调)。除非服务绑定到客户端(解绑回调 onUnbind()),否则在服务停止时,系统会将其销毁(onDestroy() 是接收到的唯一回调)。

已启动且允许绑定的服务的生命周期

  • onRebind() 方法会回调的前提是:服务未被销毁,再次绑定时回调,并且 onUnbind() 方法返回true。
  • onRebind() 返回空值,但客户端仍会回调 ServiceConnectiononServiceConnected() 方法,接收IBinder。

Service 部分相关方法详细说明

onStartCommand()

当另一个组件(如 Activity)请求启动服务时,系统会通过调用 startService() 来调用此方法。

参数:

  1. Intent intent:调用 stopService(Intent name) 方法传递的 Intent 对象,组件可以通过Intent传递参数给Service,如果之后服务重新启动,可能为null,具体是否需要有数据,需要根据该方法的返回值确定。
  2. int flags:其他附加数据。
  3. int startId:表示要启动的特定请求的唯一整数。一般与 stopSelfResult(int) 一起使用。

返回值:

一般来说,主要有三类返回值

  1. START_STICKY:如果系统在 onStartCommand() 返回后终止服务,则其会重建服务并调用 onStartCommand(),但不会重新传递最后一个 Intent。如果还有挂起 Intent 要启动服务,系统会传递这些 Intent;否则系统会调用包含空 Intent 的 onStartCommand()。此常量适用于不执行命令、但无限期运行并等待作业的媒体播放器(或类似服务)。
  2. START_STICKY_COMPATIBILITY:START_STICKY 的兼容版本。
  3. START_NOT_STICKY:如果系统在 onStartCommand() 返回后终止服务,除非有待传递的挂起的 Intent,否则系统不会重建服务。
  4. START_REDELIVER_INTENT:如果系统在 onStartCommand() 返回后终止服务,则其会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()。所有挂起 Intent 均依次传递。此常量适用于主动执行应立即恢复的作业(例如下载文件)的服务。

bindService()

用于绑定服务的方法

参数:

  1. Intent service:意图,标识要连接的服务。(注意:如果使用 Intent 来绑定到 Service,请务必使用显式 Intent 来确保应用的安全性。使用隐式 Intent 启动服务存在安全隐患,因为无法确定哪些服务会响应该 Intent,并且用户无法看到哪些服务已启动。从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用 bindService(),则系统会抛出异常。
  2. ServiceConnection conn:ServiceConnection 对象,在在服务启动和断开连接时接收信息,不能为null
  3. int flags:指示绑定选项的标记。如要创建尚未处于活动状态的服务,此参数应为 BIND_AUTO_CREATE(常用)。其他可能的值为 BIND_DEBUG_UNBIND(主要用于调试)、BIND_NOT_FOREGROUND 等,或者 0(表示无此参数)。
  4. 实现 ServiceConnection 必须重写两个回调方法:
    1. onServiceConnected() :系统会调用该方法,进而传递服务的 onBind() 方法所返回的 IBinder
    2. onServiceDisconnected():当与服务的连接意外中断(例如服务崩溃或被终止)时,Android 系统会调用该方法。当客户端取消绑定时,系统不会调用该方法。

onUnbind()

当所有客户端都和服务解除绑定时调用。如果返回true,当服务未销毁并重新调用 bindService() 时回调 onRebind()ServiceConnectiononServiceConnected() 方法;否则,只会回调 ServiceConnectiononServiceConnected() 方法。

startForeground() / stopForeground()

startForeground():让服务运行在前台,参数1:通知标识(不能为 0)参数2:用于状态栏的 Notification
stopForeground():移出前台运行的服务,参数表示是否需同时移除状态栏通知。此方法并不会停止服务。但是,如果在服务运行于前台时将其停止,则通知也会随之移除

startForegroundService()

在Android 8.0 以上系统不允许后台应用创建后台服务。 因此引入了一种全新的方法,即通过 Context.startForegroundService() 方法在前台启动新服务,通过调用该方法,在系统创建服务后,应用有五秒的时间来调用该服务的 startForeground() 方法以显示新服务的用户可见通知,如果应用在此时间限制内未调用 startForeground(),则系统将停止服务并声明此应用为 ANR。

清单文件中 Service 配置

语法

<service android:description="string resource"
     android:directBootAware=["true" | "false"]
     android:enabled=["true" | "false"]
     android:exported=["true" | "false"]
     android:foregroundServiceType=["connectedDevice" | "dataSync" |
                                    "location" | "mediaPlayback" | "mediaProjection" |
                                    "phoneCall"]
     android:icon="drawable resource"
     android:isolatedProcess=["true" | "false"]
     android:label="string resource"
     android:name="string"
     android:permission="string"
     android:process="string" >
    . . .
</service>

具体说明

android:description

向用户描述服务的字符串。应将此标签设置为对字符串资源的引用,以便可以像对界面中的其他字符串那样对其进行本地化。

android:directBootAware

服务是否支持直接启动,即其是否可以在用户解锁设备之前运行。默认值为 “false”。在直接启动期间,应用中的服务仅可访问存储在设备保护存储区的数据。

android:enabled

系统是否可实例化服务 —“true”表示可以,“false”表示不可以。默认值为“true”。

元素拥有自己的 enabled 属性,该属性适用于所有应用组件,包括服务。只有在 和 属性都为“true”(因为它们都默认使用该值)时,系统才能启用服务。任何一项为“false”都会造成服务停用,从而使系统无法将其实例化。

android:exported

其他应用的组件是否能调用服务或与之交互 —“true”表示可以,“false”表示不可以。当该值为“false”时,只有同一个应用或具有相同用户 ID 的应用的组件可以启动服务或绑定到服务。

默认值取决于服务是否包含 Intent 过滤器。没有任何过滤器意味着服务只能通过指定其确切的类名称进行调用。这意味着服务专供应用内部使用(因为其他应用不知晓其类名称)。因此,在这种情况下,默认值为“false”。另一方面,至少存在一个过滤器意味着服务专供外部使用,因此默认值为“true”。此属性并非是唯一限制向其他应用披露服务的方式。还可使用权限来限制哪些外部实体可以与服务交互。

android:foregroundServiceType

阐明服务是满足特定用例要求的前台服务。例如,“location” 类型的前台服务表示应用正在获取设备的当前位置,目的通常是继续用户发起的操作,且该操作与设备位置相关。可以将多个前台服务类型分配给特定服务。
####android:icon
表示服务的图标。必须将该属性设置为对包含图像定义的可绘制资源的引用。如果未设置该属性,则转而使用为应用整体指定的图标。

android:isolatedProcess

如果设置为 true,则此服务将在与系统其余部分隔离的特殊进程下运行。此服务自身没有权限,只能通过 Service API 与其进行通信(绑定和启动)。

android:label

可向用户显示的服务名称。如果未设置该属性,则转而使用为应用整体设置的标签。

android:name

实现服务的 Service 子类的名称。此名称应为完全限定类名称(例如“com.example.project.RoomService”)。一旦发布应用,即不应更改该名称(除非设置了 android:exported=“false”)。没有默认值。必须指定该名称。

android:permission

实体启动服务或绑定到服务所必需的权限的名称。如果 startService()、bindService() 或 stopService() 的调用者尚未获得此权限,该方法将不起作用,且系统不会将 Intent 对象传送给服务。如果未设置该属性,则对服务应用由 元素的 permission 属性所设置的权限。如果二者均未设置,则服务不受权限保护。

android:process

将运行服务的进程的名称。正常情况下,应用的所有组件都会在为应用创建的默认进程中运行。该名称与应用软件包的名称相同。 元素的 process 属性可为所有组件设置不同的默认进程名称。不过,组件可以使用自己的 process 属性替换默认值,可以将应用散布到多个进程中。

如果为此属性分配的名称以冒号(“:”)开头,则系统会在需要时创建应用专用的新进程,并且服务会在该进程中运行。如果进程名称以小写字符开头,则服务将在使用该名称的全局进程中运行,前提是它拥有相应的权限。如此一来,不同应用中的组件便可共享进程,从而减少资源使用。

软件
前端设计
程序设计
Java相关