前言
服务卡片的征文活动也已经接近尾声,在这段时间里,论坛里有许多优秀的服务卡片作品和相关的文章涌现。我拜读了专栏中几乎所有的服务卡片的开发分享文章,从每一篇文章中提取并汲取精华,整合到本文中。一些较为显然的介绍性的内容在本文中将会被省略(如卡片有多少种尺寸之类),但是一些即使在很多文章都已经说明过的,而我又认为比较重要的内容,我仍然会再次记录下来(例如卡片的框架)。另外,作为学习笔记,我会记录下一些我在学习种遇到的新的名词的概念,这些概念可能是大家已经熟知的,这部分大家可以直接忽略;文章的内容整合自论坛种的众多文章,所以大家可能会在本文中看到自己文章的影子。
服务卡片的框架
服务卡片整体框架主要包含三部分:卡片使用方、卡片管理服务和卡片提供方。其概念分别如下:
● 卡片使用方:显示卡片内容的宿主应用,控制卡片在宿主中展示的位置,如桌面、服务中心、搜索等。
● 卡片管理服务:用于管理系统中所添加卡片的常驻代理服务,包括卡片对象的管理与使用,以及卡片周期性刷新等。
● 卡片提供方:提供卡片显示内容的HarmonyOS应用或原子化服务,控制卡片的显示内容、控件布局以及控件点击事件。
卡片的运行框架有如下示意图:
简明版示意图
详细版示意图
卡片的常用功能
Java卡片与JS卡片功能的对比图
MainAbility的自动生成函数解析
在新建服务卡片的时候,在MainAbility类中将会生成一些回调方法,具体方法及其回调条件如下图,在后面的具体的卡片操作中,也会再次声明所调用的回调方法。
在onCreatForm(Intent)方法中,卡片提供方被拉起后intent会携带卡片相关信息,具体如下:
服务卡片生命周期回调函数时序如下:
配置卡片编辑功能
有些服务卡片需要具备可编辑能力,如天气App需要编辑所在城市。具体实现方法如下:在config.json中,对某一个form的配置增加formConfigAbility的属性配置,可实现编辑功能。formConfigAbility的值是一个url格式的Ability名称。若不配置formConfigAbility,则不显示编辑菜单。示例代码如下:(摘抄自[一文看懂HarmonyOS服务卡片运行原理和开发方法])(https://harmonyos.oss-cn-beijing.aliyuncs.com/images/202106/830a107135e5fa06fa1714ebaa9fa523833da2.jpg?x-oss-process=image/resize,w_1080,h_478)
卡片的定点/定时刷新:将回调updateForm()方法
运作机制示意图如下:
注意:定时刷新和定点刷新都配置的情况下,定时刷新优先。
JS卡片的定点更新步骤:
1.关闭定时更新:updateDuration”修改为0,以关闭定时刷新(config.json文件中)
2.设定“scheduledUpdateTime”的时刻
3.在具体的xxxxlmpl中重写updateFormData()方法
4.把需要刷新的数据存入一个ZSONObject实例中
5.将这个实例封装在一个FormBindingData的实例bindingData中
6.调用MainAbility的方法updateForm(),并将bindingData作为第二个实参。
JS卡片重写updateFormData()方法的代码如下:
JAVA卡片的定点更新步骤:
1.前三步与JS卡片相同
2.构造一个ComponentProvider的实例,用于表示一个Java卡片实例,传入的第一个实参是根据卡片尺寸得到的布局文件。然后,调用方法setText()修改卡片的标题;最后,调用MainAbility的方法updateForm(),并将componentProvider作为第二个实参。
JAVA卡片重写updateFormData()方法的代码如下:
卡片的定时刷新
卡片的定时刷新的最小单位时间是三十分钟,这就带来了两个问题:
1.创建卡片后的最初的三十分钟是不会进行卡片刷新的,所以需要进行手动的刷新。
2.如果是编写刷新间隔小于三十分的卡片(如时钟卡片每一秒刷新一次),那么需要自己重新创建一个timer实例来设定刷新时间。
添加手动刷新:用onCreateForm()调用onUpdateForm(formId)即可,代码摘抄自亮子力的哔哩哔哩卡片
- @Override
- protected ProviderFormInfo onCreateForm(Intent intent) {
- ... ...
- //初始化时先在线更新一下卡片
- onUpdateForm(formId);
- return formController.bindFormData();
- }
重新编写刷新时间的代码为代码摘抄自Codelabs 之 时钟FA卡片开发样例
- private void startTimer() {
- Timer timer = new Timer();
- timer.schedule(
- new TimerTask() {
- @Override
- public void run() {
- updateForms();
- }
- },
- 0,
- SEND_PERIOD);
- }
- private void updateForms() {
- // 从数据库中获取卡片信息
- HiLog.info(LABEL, "从数据库中获取卡片");
- OrmPredicates ormPredicates = new OrmPredicates(Form.class);
- List<Form> formList = connect.query(ormPredicates);
- int layoutId=0;
- // 更新时分秒
- if (formList.size() <= 0) {
- return;
- }
- HiLog.info(LABEL, "遍历卡片列表,逐个更新");
- for (Form form : formList) {
- // 遍历卡片列表更新卡片
- ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, this);
- try {
- Long updateFormId = form.getFormId();
- HiLog.info(LABEL, "updateForm,更新卡片[:"+updateFormId+"] 的数据,并非数据库操作" );
- //更新卡片数据
- boolean isSucc=updateForm(updateFormId, componentProvider);
- HiLog.info(LABEL, "更新卡片数据完成,"+isSucc);
- } catch (FormException e) {
- // 删除不存在的卡片
- DatabaseUtils.deleteFormData(form.getFormId(), connect);
- HiLog.error(LABEL, "更新卡片异常,删除数据库中不存在的卡片");
- }
- }
- }