OpenHarmonyApp启动页后记

1 回顾

通过DevEco Studio端云协同开发OpenHarmony/HarmonyOS应用程序(以下简称应用)集成AppGallery Connect(以下简称AGC)平台云函数云数据库云存储三篇文章笔者从创建端云协同应用程序开始,逐步对云函数、云数据库、云存储简单的数据读取做了简单的介绍。通过使用云数据库、云存储相结合的方式使应用的启动页能够动态化,即可以在不更新应用的情况下更改启动页的参数已达到启动页的动态化。

2 问题及解决方案

问题: 由于启动页参数来源于云数据库、云存储,启动页数据渲染前会受网络影响出现白屏。

解决方案: 为启动页数据单独封装获取方法,在启动页新增状态值,数据未加载完成后显示当前应用的icon图标,数据加载完成后渲染实际获取到的数据。

注: 若读者有其他的处理方法可与笔者共同探讨一下。

3 优化调用方法

使用async将函数异步化,使用await获取Promise的值。

3.1 云数据库获取数据方法异步化

每次使用存储区都要在使用完成后释放,新增关闭存储区方法。

// service/CloudDBService.ts
// @ts-ignore
import * as schema from './app-schema.json';
import { splash } from './splash';
import {
    AGConnectCloudDB,
    CloudDBZoneConfig,
    CloudDBZone,
    CloudDBZoneQuery
} from '@hw-agconnect/database-ohos';

import { AGCRoutePolicy } from '@hw-agconnect/core-ohos';

import { getAGConnect } from './AgcConfig';

export class CloudDBService {

    private static readonly ZONE_NAME = "cloudDBZoneSplash";
    private static cloudDB: AGConnectCloudDB;
    private static cloudDBZone: CloudDBZone;
    private static isInit: boolean;

    public static async init(context: any): Promise<boolean> {
        if (this.isInit) {
            return;
        }
        try {
            // 初始化agc
            getAGConnect(context);
            // 初始化Cloud DB
            await AGConnectCloudDB.initialize(context);
            // 获取对应数据处理位置的CloudDB实例
            this.cloudDB = await AGConnectCloudDB.getInstance(AGCRoutePolicy.CHINA);
            // 创建对象类型
            this.cloudDB.createObjectType(schema);
            // 打开存储区
            await this.openZone(this.ZONE_NAME);
            this.isInit = true;
        } catch (err) {
            console.error(JSON.stringify(err))
        }
        return Promise.resolve(this.isInit);
    }

    // 打开存储区
    private static async openZone(zoneName: string): Promise<CloudDBZone> {
        if (this.cloudDBZone) {
            return;
        }
        try {
            const cloudDBZoneConfig = new CloudDBZoneConfig(zoneName);
            this.cloudDBZone = await this.cloudDB.openCloudDBZone(cloudDBZoneConfig);
        } catch (err) {
            console.error(JSON.stringify(err));
        }
    }

    // 关闭存储区
    public static async closeZone(): Promise<void> {
        try {
            this.cloudDB.closeCloudDBZone(this.cloudDBZone);
            this.cloudDBZone = null;
        } catch (err) {
            console.error(JSON.stringify(err))
        }
    }

    public static async query(): Promise<splash> {
        try {
            const query = CloudDBZoneQuery.where(splash).equalTo("status", 1);
            const result = await this.cloudDBZone.executeQuery(query);
            return result.getSnapshotObjects().length > 0 ? result.getSnapshotObjects()[0] : new splash();
        } catch (err) {
            console.error(JSON.stringify(err));
        }
    }
}

3.2 云存储获取数据方法异步化

// services/cloudstorage/CloudStorageService.ts
import agconnect from '@hw-agconnect/api-ohos';
import "@hw-agconnect/cloudstorage-ohos";

import { getAGConnect } from '../AgcConfig';

export class CloudStorageService {

    public static async init(context: any, path: string): Promise<string> {
        try {
            getAGConnect(context);
            // 初始化默认实例
            const storage = agconnect.cloudStorage();
            // 创建需要下载文件的引用
            const storageReference = await storage.storageReference();
            var reference = await storageReference.child(path);
            return reference.getDownloadURL();
        } catch (err) {
            console.error(JSON.stringify(err));
        }
    }
}

4 为启动页数据获取封装专用方法

可以将一些处理逻辑放在该方法中处理。

// services/SplashService.ts
import { splash } from './splash';
import { CloudDBService } from '../services/CloudDBService';
import { CloudStorageService } from '../services/cloudstorage/CloudStorageService';

export class SplashService {

    public static async querySplash(context: any): Promise<splash> {
        try {
            await CloudDBService.init(context);
            let splash = await CloudDBService.query();
            let url = await CloudStorageService.init(context, splash.backgroundImg);
            splash.backgroundImg = url;
            await CloudDBService.closeZone();
            return splash;
        } catch (err) {
            console.error(JSON.stringify(err));
        }
    }
}

5 改写启动页

启动页新增状态码,用于数据未加载完成呈现给用户的显示界面,规避数据未获取导致的白屏现象。

@State isSkip: boolean = false;

aboutToAppear()方法中执行获取启动页数据的方法。

aboutToAppear() {
    this.isSkip = false;
    SplashService.querySplash(getContext(this)).then((ret) => {
      this.isSkip = true;
      this.result = ret;
    })
  }

页面中使用if(){}else{}条件语句判断渲染的组件,从而规避数据请求时间导致的白屏现象。

if (this.isSkip) {
  SplashPage({ mSplash: {
    timer: this.result.timer,
    isLogo: this.result.isLogo,
    backgroundImg: this.result.backgroundImg,
    companyName: this.result.companyName,
    mFontColor: this.result.mFontColor
  }, skip: this.onSkip })
} else {
  Column() {
    Image($r('app.media.icon')).objectFit(ImageFit.None)
  }
  .width('100%').height('100%')
}

通过更改AGC平台云数据库中启动页数据状态,可以实现下次启动应用程序,启动页呈现不同内容。使用场景如新闻类App可以在启动页呈现一条配备图片的热文;常规App可以在启动页呈现一条经典语录;实现不同节日在启动页呈现问候信息。

6 后记

本文所记为之前文章的总结,针对获取AGC平台各项服务的数据,可直接调用对应的方法即可。若出现复杂的情况,如后面笔者将实现认证服务登录,并将用户信息存储到云数据库中,可以结合云函数,在用户登录的时候,直接调用云函数去保存用户信息,存储方法可以通过云函数的AUTH触发器实现数据存储云数据库中;再如用户上传图片,生成缩略图,也可以利用云函数将原图和缩略图一同保存到云存储中。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350