OpenHarmonyApp啟動(dòng)頁(yè)后記

1 回顧

通過(guò)DevEco Studio端云協(xié)同開(kāi)發(fā)OpenHarmony/HarmonyOS應(yīng)用程序(以下簡(jiǎn)稱應(yīng)用)集成AppGallery Connect(以下簡(jiǎn)稱AGC)平臺(tái)云函數(shù)、云數(shù)據(jù)庫(kù)、云存儲(chǔ)三篇文章筆者從創(chuàng)建端云協(xié)同應(yīng)用程序開(kāi)始,逐步對(duì)云函數(shù)、云數(shù)據(jù)庫(kù)、云存儲(chǔ)簡(jiǎn)單的數(shù)據(jù)讀取做了簡(jiǎn)單的介紹。通過(guò)使用云數(shù)據(jù)庫(kù)、云存儲(chǔ)相結(jié)合的方式使應(yīng)用的啟動(dòng)頁(yè)能夠動(dòng)態(tài)化,即可以在不更新應(yīng)用的情況下更改啟動(dòng)頁(yè)的參數(shù)已達(dá)到啟動(dòng)頁(yè)的動(dòng)態(tài)化。

2 問(wèn)題及解決方案

問(wèn)題: 由于啟動(dòng)頁(yè)參數(shù)來(lái)源于云數(shù)據(jù)庫(kù)、云存儲(chǔ),啟動(dòng)頁(yè)數(shù)據(jù)渲染前會(huì)受網(wǎng)絡(luò)影響出現(xiàn)白屏。

解決方案: 為啟動(dòng)頁(yè)數(shù)據(jù)單獨(dú)封裝獲取方法,在啟動(dòng)頁(yè)新增狀態(tài)值,數(shù)據(jù)未加載完成后顯示當(dāng)前應(yīng)用的icon圖標(biāo),數(shù)據(jù)加載完成后渲染實(shí)際獲取到的數(shù)據(jù)。

注: 若讀者有其他的處理方法可與筆者共同探討一下。

3 優(yōu)化調(diào)用方法

使用async將函數(shù)異步化,使用await獲取Promise的值。

3.1 云數(shù)據(jù)庫(kù)獲取數(shù)據(jù)方法異步化

每次使用存儲(chǔ)區(qū)都要在使用完成后釋放,新增關(guān)閉存儲(chǔ)區(qū)方法。

// 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);
            // 獲取對(duì)應(yīng)數(shù)據(jù)處理位置的CloudDB實(shí)例
            this.cloudDB = await AGConnectCloudDB.getInstance(AGCRoutePolicy.CHINA);
            // 創(chuàng)建對(duì)象類型
            this.cloudDB.createObjectType(schema);
            // 打開(kāi)存儲(chǔ)區(qū)
            await this.openZone(this.ZONE_NAME);
            this.isInit = true;
        } catch (err) {
            console.error(JSON.stringify(err))
        }
        return Promise.resolve(this.isInit);
    }

    // 打開(kāi)存儲(chǔ)區(qū)
    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));
        }
    }

    // 關(guān)閉存儲(chǔ)區(qū)
    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 云存儲(chǔ)獲取數(shù)據(jù)方法異步化

// 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);
            // 初始化默認(rèn)實(shí)例
            const storage = agconnect.cloudStorage();
            // 創(chuàng)建需要下載文件的引用
            const storageReference = await storage.storageReference();
            var reference = await storageReference.child(path);
            return reference.getDownloadURL();
        } catch (err) {
            console.error(JSON.stringify(err));
        }
    }
}

4 為啟動(dòng)頁(yè)數(shù)據(jù)獲取封裝專用方法

可以將一些處理邏輯放在該方法中處理。

// 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 改寫啟動(dòng)頁(yè)

啟動(dòng)頁(yè)新增狀態(tài)碼,用于數(shù)據(jù)未加載完成呈現(xiàn)給用戶的顯示界面,規(guī)避數(shù)據(jù)未獲取導(dǎo)致的白屏現(xiàn)象。

@State isSkip: boolean = false;

aboutToAppear()方法中執(zhí)行獲取啟動(dòng)頁(yè)數(shù)據(jù)的方法。

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

頁(yè)面中使用if(){}else{}條件語(yǔ)句判斷渲染的組件,從而規(guī)避數(shù)據(jù)請(qǐng)求時(shí)間導(dǎo)致的白屏現(xiàn)象。

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%')
}

通過(guò)更改AGC平臺(tái)云數(shù)據(jù)庫(kù)中啟動(dòng)頁(yè)數(shù)據(jù)狀態(tài),可以實(shí)現(xiàn)下次啟動(dòng)應(yīng)用程序,啟動(dòng)頁(yè)呈現(xiàn)不同內(nèi)容。使用場(chǎng)景如新聞?lì)怉pp可以在啟動(dòng)頁(yè)呈現(xiàn)一條配備圖片的熱文;常規(guī)App可以在啟動(dòng)頁(yè)呈現(xiàn)一條經(jīng)典語(yǔ)錄;實(shí)現(xiàn)不同節(jié)日在啟動(dòng)頁(yè)呈現(xiàn)問(wèn)候信息。

6 后記

本文所記為之前文章的總結(jié),針對(duì)獲取AGC平臺(tái)各項(xiàng)服務(wù)的數(shù)據(jù),可直接調(diào)用對(duì)應(yīng)的方法即可。若出現(xiàn)復(fù)雜的情況,如后面筆者將實(shí)現(xiàn)認(rèn)證服務(wù)登錄,并將用戶信息存儲(chǔ)到云數(shù)據(jù)庫(kù)中,可以結(jié)合云函數(shù),在用戶登錄的時(shí)候,直接調(diào)用云函數(shù)去保存用戶信息,存儲(chǔ)方法可以通過(guò)云函數(shù)的AUTH觸發(fā)器實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)云數(shù)據(jù)庫(kù)中;再如用戶上傳圖片,生成縮略圖,也可以利用云函數(shù)將原圖和縮略圖一同保存到云存儲(chǔ)中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容