欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Service回调和配置

程序员文章站 2022-07-10 18:48:28
Service 生命周期方法回调创建服务,必须创建 Service 的子类(或使用它的一个现有子类)。可以重写一些回调方法,从而处理服务生命周期的某些关键方面,主要的回调方法有 onCreate()、onBind()、onRebind()、onStartCommand()、onStart()、onUnbind()、onDestroy()。onCreate()首次创建服务时,系统会(在调用 onStartCommand() 或 onBind() 之前)调用此方法来执行一次性设置程序。如果服务已在运行,则...

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 生命周期流程图

服务生命周期图

Android Service回调和配置

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

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

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

Android Service回调和配置

  • 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 属性替换默认值,可以将应用散布到多个进程中。

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

本文地址:https://blog.csdn.net/ITRenj/article/details/108860672