鴻蒙項目加入廣告展示頁業務
廣告頁的思路——華為有廣告業務,但是我們不用- ad模塊;
想自定義廣告——場景: app啟動-有廣告需求,就打開廣告頁,沒有的話就去登錄或者主頁;
騰訊體育的廣告- 啟動有廣告頁,退到后臺的情況下,再次進入前臺也會有廣告;
一、分析需求:
廣告頁作為一個app啟動的首頁,應該是在我們應用啟動就進去的。
-
有的app有的需要廣告頁,有的不需要,搞個配置唄!!!
二、思路
-
通過首選項配置存儲我們的一些常用配置,比如要不要廣告頁,還有廣告頁的路由地址,點擊廣告頁跳轉的鏈接,廣告頁倒計時的秒數
-
在入口處進行判斷是否需要廣告頁,需要的話,跳轉廣告頁-廣告頁根據設置的參數進行渲染
-
問題來了,因為運營人員肯定不能每次都去改我們底層的代碼-這里我還可以設置成動態的-就是初始化的時候通過請求去讀一下云端的請求,然后把我們的圖片和一些參數配置下來,這樣每次你啟動app就是運營人員給你配置的廣告和設置了
三、開搞
-
新建一個關于廣告類的數據模型-basic- models/advert.ets
export class AdvertClass {showAd: boolean = false // 顯示廣告adTime: number = 5 // 廣告時長adUrl?: string = '' // 廣告鏈接adImg?: ResourceStr = '' // 廣告圖片
}
-
在model/index.ets中進行統一導出
export * from './advert'
-
在utils中新建一個關于讀取首選項的類,用來讀取和設置首選項的廣告設置- utils/setting.ets
import { AdvertClass } from '../models'
import preferences from '@ohos.data.preferences'
import { USER_SETTING, USER_SETTING_AD } from '../constants'
// 默認廣告選項
const defaultAd: AdvertClass = {showAd: true,adTime: 5,adImg: $r('app.media.start')
}
export class UserSettingClass {context: Contextconstructor(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))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}
}
在上面代碼中,我們設計了讀取和設置廣告的兩個方法,并且提供了一個默認廣告的設置
-
在utils中統一導出
export * from './setting'
-
上面還用到了兩個常量,我們同樣需要在constants目錄下定義一個文件專門用來記錄-setting
export const USER_SETTING = 'fast_driver_setting' // 用來存儲用戶設置的首選項的key
export const USER_SETTING_AD = 'fast_driver_setting_ad' // 用來存儲用戶設置廣告首選項的key
-
同樣在constants/index.ets文件中導出
export * from './setting'
-
在basic/Index.ets統一導出
export * from './src/main/ets/models'
export * from './src/main/ets/constants'
export * from './src/main/ets/utils'
entry模塊-oh-package.json5
-
在ability中引入該har包依賴
{"name": "entry","version": "1.0.0","description": "Please describe the basic information.","main": "","author": "","license": "","dependencies": {"@hm/basic":"file:../common/basic"}
}
ability中判斷
-
導入包
import { AdvertClass, UserSettingClass } from '@hm/basic'
-
判斷
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {// Main window is created, set main page for this ability// 檢查是否有廣告const setting = new UserSettingClass(this.context) // getContext拿到的是undefined//const ad = await new Promise<AdvertClass>((resolve, reject) => {setTimeout(() => {resolve(defaultAd) // 廣告信息}, 500)// resolve()})// 通過模擬請求拿到廣告信息await setting.setUserAd(ad) // 寫入首選項if(ad.showAd) {// 展示廣告的情況 展示廣告頁 有時限// 創建一個子窗口 子窗口加載廣告 廣告播完 窗口銷毀}windowStage.loadContent('pages/Index'); // 正常加載頁面}
這里我們模擬了一個請求,給了一個默認廣告, 寫入首選項-正常加載主頁
-
在pages下新建Start目錄,下面新建Start的page頁面
-
實現Start頁的頁面結構及倒計時邏輯
import { UserSettingClass, AdvertClass } from '@hm/basic'
?
@Entry
@Component
struct Start {userSetting: UserSettingClass = new UserSettingClass(getContext(this))@StateadObj: AdvertClass ?= {showAd: false,adTime: 0}timer: number = -1async aboutToAppear() {this.adObj = await this.userSetting.getUserAd()this.timer = setInterval(() => {if(this.adObj.adTime === 0) {clearInterval(this.timer)return}this.adObj.adTime--}, 1000)}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%')}
}
-
使用子窗口模式加載廣告
我們可以使用windowStage的createSubWindow來實現在當前頁面上創建一個窗口
if (result.showAd) {const win = await windowStage.createSubWindow("ad_window")await win.showWindow()win.setUIContent("pages/Start/Start")}
-
廣告頁在廣告結束或者點擊跳過廣告時,關閉廣告
Start/Start頁面
closeWin () {window.findWindow("ad_window").destroyWindow()
}
-
完成Start頁面代碼
import { UserSettingClass, AdvertClass } from '@hm/basic'
import { window } from '@kit.ArkUI'
?
@Entry
@Component
struct Start {userSetting: UserSettingClass = new UserSettingClass(getContext(this))@StateadObj: AdvertClass ?= {showAd: false,adTime: 0}timer: number = -1closeWin () {window.findWindow("ad_window").destroyWindow()}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)} 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).onClick(() => {this.closeWin()})
?}.height('100%').width('100%')}
}
這里請注意-如果需要使用線上的廣告圖片,需要開啟網絡權限
完整代碼-EntryAbility
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { AdvertClass, UserSettingClass } from '@hm/basic'
?
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 abilityhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');// 這里要嘗試去讀一下運營的配置-我們現在還沒有實現接口,直接模擬一下const userSetting = new UserSettingClass(this.context)const result = await new Promise<AdvertClass>((resolve, reject) => {setTimeout(() => {resolve({showAd: true,adTime: 5,adImg: $r("app.media.start")} as AdvertClass)}, 500)})await userSetting.setUserAd(result) // 寫入首選項if (result.showAd) {const win = await windowStage.createSubWindow("ad_window")await win.showWindow()win.setUIContent("pages/Start/Start")}windowStage.loadContent('pages/Index');}
?onWindowStageDestroy(): void {// Main window is destroyed, release UI related resourceshilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');}
?onForeground(): void {// Ability has brought to foregroundhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');}
?onBackground(): void {// Ability has back to backgroundhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');}
}
到此廣告功能就搞定了!