Erlo

HarmonyOS3.0尝鲜之关键Js Api#sql_zs#ServiceAbility开发

收藏 2022-08-19 15:01:09   54   开源中国
页面报错/反馈
点赞

HarmonyOS3.0发布之后,大家可以从api8上可以看到一个关键动作,就是完全抛弃了java,并且不提供对api8以下版本的兼容,完全颠覆性变化,显然不可能再去兼容低版本了。那么做过api7之前开发的朋友都会知道,在之前的js或者ets开发中,有几个关键地方是离不开java的,比如我前面一篇博客中写道的动态权限申请,本篇将来介绍另一个关键技术ServiceAbility,之前的ServiceAbility是完全基于Java开发,可以说和Android里面的开发模式一样。
下面就来上手尝试下ServiceAbility纯粹js或者ets开发吧,这里稍微吐槽下官方文档的不足吧,我已经反馈官方整改文档了。文档上的一些小错误和不足导致我打通Service的所有核心技能足足耗费了十多个小时,其中最难的莫过于Service主动给FA推送数据了,做过Android的可能都知道在Android里面这个是基于java的回调机制来实现,而这里官方文档是没有说这个核心技能是如何实现的,js的回调机制和java的回调机制还是有非常大区别的,我开始专在回调里面出不来导致耗费了很久时间,最后又尝试了N中方案终于最后找到了最优解搞定了这个核心功能。
本篇文章先主要来个Js版本的ServiceAbility开发入门吧。

场景介绍

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

接口说明

表1 Service中相关生命周期功能介绍

image.png

开发步骤

本篇先只实现最基本的创建、启动和停止Service。

创建工程

首先使用最新版的DevEco Studio(992版本)开发工具创建一个工程,选择最新的api8,如下图

image.png

image.png

创建工程时,需要关注的就是上图中所描述的bundleName和package,因为后面核心api中要使用到这两个参数,对于这两个参数含义不清楚的可以查阅我另外一篇博客《App与Hap、Entry与feature,bundleName与packge,务必弄明白

创建Service

工程创建完成之后,鼠标选择js目录,然后点击鼠标右键,如下图依次选择来创建Service

image.png

image.png

Service也是一种Ability,Ability为Service提供了以下生命周期方法,开发者可以重写这些方法,来添加其他Ability请求与Service Ability交互时的处理方法。

创建Service的代码示例如下:

export default {
    onStart(want) {
        console.info('ServiceAbility onStart');
    },
    onStop() {
        console.info('ServiceAbility onStop');
    },
    onConnect(want) {
        console.info('ServiceAbility onConnect');
        return {};
    },
    onReconnect(want) {
        console.info('ServiceAbility onReconnect');
    },
    onDisconnect() {
        console.info('ServiceAbility onDisconnect');
    },
    onCommand(want, restart, startId) {
        console.info('ServiceAbility onCommand');
    }
};

本篇将只讲解启动和停止服务,等会写完启动和停止服务的触发代码之后,我们再来看看会有哪些生命周期函数会被回调。

由于Service也是Ability,创建完成Service之后,它也会自动的在应用配置文件config.json中生成相关核心配置信息,其中有个核心配置就是type为“service”,具体如下所示:

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

启动Service

做个极其简单的页面,只放置两个文本按钮,分别用来触发“启动Service”和“停止Service”,如下图

image.png

Ability为开发者提供了startAbility()方法来启动另外一个Ability。因为Service也是Ability的一种,开发者同样可以通过将Want传递给该方法来启动Service。

开发者可以通过构造包含bundleName与abilityName的Want对象来设置目标Service信息。参数的含义如下:
- bundleName:表示应用唯一标识符名称,即config.json中的bundleName。
- abilityName:表示待启动的Ability名称,这里使用完整Ability名称,即package+‘.’+Ability名称。
启动本地设备Service的代码示例如下:
首先要导入系统库
import featureAbility from ‘@ohos.ability.featureAbility’;

然后业务逻辑代码如下:

    //启动service按钮绑定的点击事件
    onClickStartService(){
        let promise = featureAbility.startAbility(
            {
                want:
                {
                    bundleName: "com.xdw.jsdemo",
                    abilityName: "com.example.entry.ServiceAbility",
                },
            }
        );
    }

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

- 如果Service尚未运行,则系统会先调用onStart()来初始化Service,再回调Service的onCommand()方法来启动Service。
- 如果Service正在运行,则系统会直接回调Service的onCommand()方法来启动Service。
不支持预览器进行测试,下面启动模拟器或者真机(必须api》=8)进行测试,多次点击“启动Service”按钮观察日志输出,日志输出如下图

image.png

停止Service

Service一旦创建就会一直保持在后台运行,除非必须回收内存资源,否则系统不会停止或销毁Service。开发者可以在Service中通过featureAbility.terminateSelf()停止本Service。
这里需要注意的是官方sdk目前并没有提供在其他Ability中主动停止Service的api,因此现在想简简单单的在UI中点击“停止service”按钮直接调用一个api停止service是做不到的,但并不是代表就不能通过点击按钮来停止服务,关于这个的实现下篇再讲。这里只讲通过在当前Service中通过featureAbility.terminateSelf()停止本Service。由于不是主动通过UI操作的,什么时候去停止服务需要个触发时机,最简单的就是在Service中添加一个定时器来做demo演示了。代码如下:

    onStart(want) {
        console.info('ServiceAbility onStart');
        //5秒之后停止Service
        setTimeout(()=>{
	    console.info('delay 5秒');
            featureAbility.terminateSelf();
        },5000)
    },

但是这里尝试,发现尝试了好多次之后发现目前在Service中不支持setTimout定时器的运行,还不知道是有意这么设计的还是缺陷bug,已经反馈给华为官方进行跟进。那么只能换一种最low的方式来演示了,代码如下:

    onCommand(want, restart, startId) {
        console.info('ServiceAbility onCommand');
        featureAbility.terminateSelf();
    }

最后运行日志截图如下:

image.png

小结

在官方文档基础上,把操作步骤和一些关键解释描述的更加详细,更加方便小白入手,防止入坑。
本篇只是入门级开胃小菜,我最终用这个Service的目的是为了在我智能家居的项目中,手机端通过该AbilityService实时接收服务端推送过来的数据,然后Service中接收到服务端推送过来的数据之后可以主动更新UI对应的Ability中的数据,即需要打通Service主动向Activity中传递数据这个关键技术点。详细打通流程会在下篇文章中讲解,这个是目前官网上面没有的内容。

登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认