写点什么

HarmonyOS 学习路之开发篇——Service Ability

发布于: 1 小时前

Service Ability

Service Ability 基本概念

基于 Service 模板的 Ability(以下简称“Service”)主要用于后台运行任务(如执行音乐播放、文件下载等),但不提供用户交互界面。Service 可由其他应用或 Ability 启动,即使用户切换到其他应用,Service 仍将在后台继续运行。


Service 是单实例的。在一个设备上,相同的 Service 只会存在一个实例。如果多个 Ability 共用这个实例,只有当与 Service 绑定的所有 Ability 都退出后,Service 才能够退出。由于 Service 是在主线程里执行的,因此,如果在 Service 里面的操作时间过长,开发者必须在 Service 里创建新的线程来处理,防止造成主线程阻塞,应用程序无响应。

创建 Service

介绍如何创建一个 Service。1、创建 Ability 的子类,实现 Service 相关的生命周期方法。Service 也是一种 Ability,Ability 为 Service 提供了以下生命周期方法,通过重写这些方法,来添加其他 Ability 请求与 Service Ability 交互时的处理方法。


  • onStart()该方法在创建 Service 的时候调用,用于 Service 的初始化。在 Service 的整个生命周期只会调用一次,调用时传入的 Intent 应为空。

  • onCommand()在 Service 创建完成之后调用,该方法在客户端每次启动该 Service 时都会调用,用户可以在该方法中做一些调用统计、初始化类的操作。

  • onConnect​()在 Ability 和 Service 连接时调用,该方法返回 IRemoteObject 对象,用户可以在该回调函数中生成对应 Service 的 IPC 通信通道,以便 Ability 与 Service 交互。Ability 可以多次连接同一个 Service,系统会缓存该 Service 的 IPC 通信对象,只有第一个客户端连接 Service 时,系统才会调用 Service 的 onConnect 方法来生成 IRemoteObject 对象,而后系统会将同一个 RemoteObject 对象传递至其他连接同一个 Service 的所有客户端,而无需再次调用 onConnect 方法。

  • onDisconnect​()在 Ability 与绑定的 Service 断开连接时调用。

  • onStop()在 Service 销毁时调用。Service 应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。创建 Service 的代码示例如下:


public class ServiceAbility extends Ability {    @Override    public void onStart(Intent intent) {        super.onStart(intent);    }
@Override public void onCommand(Intent intent, boolean restart, int startId) { super.onCommand(intent, restart, startId); }
@Override public IRemoteObject onConnect(Intent intent) { return super.onConnect(intent); }
@Override public void onDisconnect(Intent intent) { super.onDisconnect(intent); }
@Override public void onStop() { super.onStop(); }}
复制代码


2、注册 Service。Service 也需要在应用配置文件中进行注册,注册类型 type 需要设置为 service。


{    "module": {        "abilities": [                     {                    "name": ".ServiceAbility",                "type": "service",                "visible": true                ...            }        ]        ...    }    ...}
复制代码

启动 Service

介绍通过 startAbility()启动 Service 以及对应的停止方法。


  • 启动 ServiceAbility 为开发者提供了 startAbility()方法来启动另外一个 Ability。因为 Service 也是 Ability 的一种,开发者同样可以通过将 Intent 传递给该方法来启动 Service。不仅支持启动本地 Service,还支持启动远程 Service。开发者可以通过构造包含 DeviceId、BundleName 与 AbilityName 的 Operation 对象来设置目标 Service 信息。这三个参数的含义如下:

  • DeviceId:表示设备 ID。如果是本地设备,则可以直接留空;如果是远程设备,可以通过 ohos.distributedschedule.interwork.DeviceManager 提供的 getDeviceList 获取设备列表,详见《API 参考》。

  • BundleName:表示包名称。

  • AbilityName:表示待启动的 Ability 名称。


启动本地设备 Service 的代码示例如下:


Intent intent = new Intent();Operation operation = new Intent.OperationBuilder()        .withDeviceId("")        .withBundleName("com.domainname.hiworld.himusic")        .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")        .build();intent.setOperation(operation);startAbility(intent);
复制代码


启动远程设备 Service 的代码示例如下:


Intent intent = new Intent();Operation operation = new Intent.OperationBuilder()        .withDeviceId("deviceId")        .withBundleName("com.domainname.hiworld.himusic")        .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")        .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) // 设置支持分布式调度系统多设备启动的标识        .build();intent.setOperation(operation);startAbility(intent);
复制代码


执行上述代码后,Ability 将通过 startAbility() 方法来启动 Service。


  • 如果 Service 尚未运行,则系统会先调用 onStart()来初始化 Service,再回调 Service 的 onCommand()方法来启动 Service。

  • 如果 Service 正在运行,则系统会直接回调 Service 的 onCommand()方法来启动 Service。

  • 停止 ServiceService 一旦创建就会一直保持在后台运行,除非必须回收内存资源,否则系统不会停止或销毁 Service。开发者可以在 Service 中通过 terminateAbility()停止本 Service 或在其他 Ability 调用 stopAbility()来停止 Service。停止 Service 同样支持停止本地设备 Service 和停止远程设备 Service,使用方法与启动 Service 一样。一旦调用停止 Service 的方法,系统便会尽快销毁 Service。

连接 Service

如果 Service 需要与 Page Ability 或其他应用的 Service Ability 进行交互,则须创建用于连接的 Connection。Service 支持其他 Ability 通过 connectAbility()方法与其进行连接。


在使用 connectAbility()处理回调时,需要传入目标 Service 的 Intent 与 IAbilityConnection 的实例。IAbilityConnection 提供了两个方法供开发者实现:onAbilityConnectDone()是用来处理连接 Service 成功的回调,onAbilityDisconnectDone()是用来处理 Service 异常死亡的回调。


创建连接 Service 回调实例的代码示例如下:


// 创建连接Service回调实例private IAbilityConnection connection = new IAbilityConnection() {    // 连接到Service的回调    @Override    public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) {        // Client侧需要定义与Service侧相同的IRemoteObject实现类。开发者获取服务端传过来IRemoteObject对象,并从中解析出服务端传过来的信息。    }
// Service异常死亡的回调 @Override public void onAbilityDisconnectDone(ElementName elementName, int resultCode) { }};
复制代码


连接 Service 的代码示例如下:


// 连接ServiceIntent intent = new Intent();Operation operation = new Intent.OperationBuilder()        .withDeviceId("deviceId")        .withBundleName("com.domainname.hiworld.himusic")        .withAbilityName("com.domainname.hiworld.himusic.ServiceAbility")        .build();intent.setOperation(operation);connectAbility(intent, connection);
复制代码


同时,Service 侧也需要在 onConnect()时返回 IRemoteObject,从而定义与 Service 进行通信的接口。onConnect()需要返回一个 IRemoteObject 对象,HarmonyOS 提供了 IRemoteObject 的默认实现,用户可以通过继承 LocalRemoteObject 来创建自定义的实现类。Service 侧把自身的实例返回给调用侧的代码示例如下:


// 创建自定义IRemoteObject实现类private class MyRemoteObject extends LocalRemoteObject {    MyRemoteObject(){    }}
// 把IRemoteObject返回给客户端@Overrideprotected IRemoteObject onConnect(Intent intent) { return new MyRemoteObject();}
复制代码

Service Ability 生命周期

与 Page 类似,Service 也拥有生命周期,如图 1 所示。根据调用方法的不同,其生命周期有以下两种路径:


  • 启动 Service 该 Service 在其他 Ability 调用 startAbility()时创建,然后保持运行。其他 Ability 通过调用 stopAbility()来停止 Service,Service 停止后,系统会将其销毁。

  • 连接 Service 该 Service 在其他 Ability 调用 connectAbility()时创建,客户端可通过调用 disconnectAbility​()断开连接。多个客户端可以绑定到相同 Service,而且当所有绑定全部取消后,系统即会销毁该 Service。


图 1 Service 生命周期


前台 Service

一般情况下,Service 都是在后台运行的,后台 Service 的优先级都是比较低的,当资源不足时,系统有可能回收正在运行的后台 Service。


在一些场景下(如播放音乐),用户希望应用能够一直保持运行,此时就需要使用前台 Service。前台 Service 会始终保持正在运行的图标在系统状态栏显示。


使用前台 Service 并不复杂,开发者只需在 Service 创建的方法里,调用 keepBackgroundRunning()将 Service 与通知绑定。调用 keepBackgroundRunning()方法前需要在配置文件中声明 ohos.permission.KEEP_BACKGROUND_RUNNING 权限,同时还需要在配置文件中添加对应的 backgroundModes 参数。在 onStop()方法中调用 cancelBackgroundRunning​()方法可停止前台 Service。


使用前台 Service 的 onStart()代码示例如下:


// 创建通知,其中1005为notificationIdNotificationRequest request = new NotificationRequest(1005);NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();content.setTitle("title").setText("text");NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);request.setContent(notificationContent);
// 绑定通知,1005为创建通知时传入的notificationIdkeepBackgroundRunning(1005, request);
复制代码


在配置文件中,“module > abilities”字段下对当前 Service 做如下配置:


{        "name": ".ServiceAbility",    "type": "service",    "visible": true,    "backgroundModes": ["dataTransfer", "location"]}
复制代码


发布于: 1 小时前阅读数: 2
用户头像

还未添加个人签名 2020.05.07 加入

精通移动开发、Android开发; 熟练应用java/JavaScript进行HarmonyOS开发; 熟练使用HTML/CSS语言进行网页开发。

评论

发布
暂无评论
HarmonyOS学习路之开发篇——Service Ability