鸿蒙原生开发-如何在应用启动加上广告小窗(实现将广告存储到首选项)

276 阅读2分钟

总体功能概述

这个项目的总体功能是管理和展示广告,包括:

  1. 在应用启动时检查和加载广告设置
  2. 如果需要显示广告,在一个子窗口中展示广告
  3. 计时显示广告,并在倒计时结束后关闭广告窗口
  4. 将广告设置持久化存储在用户首选项中

整体工作流程

  1. 应用启动

    • EntryAbilityonWindowStageCreate 被调用,初始化广告设置,并存储到用户偏好中。
  2. 检查和显示广告

    • 如果广告需要显示,创建广告子窗口,并显示广告内容 Start 组件。
    • Start 组件从用户设置中获取广告信息,显示广告,并启动倒计时。
  3. 倒计时和关闭广告

    • Start 组件每秒更新广告倒计时,倒计时结束后,关闭广告窗口。

代码实现流程

1. 定义广告设置和用户设置类

代码:

// 导入 AdvertClass 模型和 Context 类
import { AdvertClass } from '../models';
import { Context } from '@kit.AbilityKit';
// 从 @kit.ArkData 导入用户偏好数据
import { preferences } from '@kit.ArkData';
// 从 ../constants 导入用户设置的常量
import { USER_SETTING, USER_SETTING_AD } from '../constants';

// 定义默认的广告设置
export const defaultAd: AdvertClass = {
  showAd: true, // 是否显示广告
  adTime: 5, // 广告时长(单位:秒)
  adImg: $r('app.media.start') // 广告图片资源
};

// 定义一个用于用户设置的类
export class UserSettingClass {
  context: Context; // 保存上下文对象

  constructor(context: Context) {
    this.context = context; // 构造函数,用于初始化上下文对象
  }

  // 获取存储用户信息的首选项仓库
  getStore() {
    return preferences.getPreferences(this.context, USER_SETTING); // 获取用户设置的首选项存储
  }

  // 设置用户广告设置
  async setUserAd(ad: AdvertClass) {
    const adStore = await this.getStore(); // 获取首选项存储对象
    await adStore.put(USER_SETTING_AD, JSON.stringify(ad)); // 将广告设置以 JSON 字符串的形式存储
    await adStore.flush(); // 刷新存储,确保数据持久化
  }

  // 获取广告配置
  async getUserAd(): Promise<AdvertClass> {
    const adStore = await this.getStore(); // 获取首选项存储对象
    return JSON.parse(await adStore.get(USER_SETTING_AD, JSON.stringify(defaultAd)) as string) as AdvertClass;
    // 从存储中获取广告设置,如果没有设置则使用默认值,并将其解析为 AdvertClass 对象
  }
}

核心:

  • UserSettingClass 提供了方法来存储和获取用户广告设置。

  • 默认广告设置 defaultAd 在代码中定义,用于在没有存储广告设置时使用。

2. 定义广告显示和管理组件

代码:

import { UserSettingClass, AdvertClass } from '@hm/basic';
import { window } from '@kit.ArkUI';

@Entry
@Component
struct Start {
  userSetting: UserSettingClass = new UserSettingClass(getContext(this));
  
  @State
  adObj: AdvertClass = {
    showAd: false,
    adTime: 0
  };
  
  timer: number = -1;
  
  async aboutToAppear() {
    this.adObj = await this.userSetting.getUserAd();
    this.timer = setInterval(() => {
      if(this.adObj.adTime === 0) {
        clearInterval(this.timer);
        this.closeWin();
        return;
      }
      this.adObj.adTime--;
    }, 1000);
  }
  
  aboutToDisappear(): void {
    clearInterval(this.timer);
  }
  
  closeWin() {
    window.findWindow('ad_window').destroyWindow();
  }
  
  build() {
    Stack({ alignContent: Alignment.TopEnd }) {
      Image(this.adObj.adImg).objectFit(ImageFit.Cover);
      Text(`${this.adObj.adTime}秒后跳过`)
        .padding({ left: 10, right: 10 })
        .margin({ right: 20, top: 20 })
        .height(30)
        .fontSize(14)
        .borderRadius(15)
        .backgroundColor($r("app.color.background_page"))
        .textAlign(TextAlign.Center);
    }.height('100%').width('100%');
  }
}

核心:

  • Start 组件负责展示广告,并且在组件出现时,开始广告倒计时。

  • 使用 setInterval 每秒更新广告时间,广告时间结束后关闭广告窗口。

3.定义主入口 Ability

代码:

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { AdvertClass, defaultAd, UserSettingClass } from '@hm/basic/Index';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
    // Main window is created, set main page for this ability
    // 检查是否有广告
    const setting = new UserSettingClass(this.context); // 获取上下文
    // 通过模拟请求拿到广告信息
    const ad = await new Promise<AdvertClass>((resolve, reject) => {
      setTimeout(() => {
        resolve(defaultAd);
      }, 500);
    });
    await setting.setUserAd(ad); // 写入首选项
    // 使用子窗口模式加载广告
    if (ad.showAd) {
      const win = await windowStage.createSubWindow('ad_window');
      await win.showWindow();
      win.setUIContent('pages/Start/Start');
    }
    windowStage.loadContent('pages/Index');
  }

  onWindowStageDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

核心:

  • EntryAbility 负责初始化应用,包括加载广告设置,并根据广告设置决定是否展示广告。

  • onWindowStageCreate 方法中,模拟异步获取广告设置,将广告设置保存到用户偏好中。

  • 如果广告设置表明需要显示广告,创建并显示广告子窗口。

  • 加载主页面内容。

总结

结合了用户设置管理、广告显示逻辑和应用生命周期管理,通过合理的代码结构,实现了广告展示的功能