写在前面
本周项目太紧了周四晚上团队大联调搞到十点半大家才回家,集中解决了一些bug,想到要整理笔记不如将这一年来项目和学习中遇到的一些小问题xiaobug小难点留下来的东西,整理成分享的内容,岂不美哉。本篇是之前遇到的问题,自己留在多个平台的线上笔记中了比价散乱,我在项目上的时候也会偶尔翻一下自己之前项目工作中留下的笔记,我们今天整理一次,后续持续更新笔记,后面遇到需要记笔记的时候,直接在平台分享啦。
一、解决状态栏白底-白字
这种解决方式是强行解决-应该有不同模式下的配置文件,这是我在2024年6月遇到的一个问题,项目着急上线,华为云的人催的很紧哈哈,征得客户负责人同意,我提出的解决方案是无论用户手机使用什么模式(浅色、暗黑),我应用内都是强制白底黑子
ts
// 1.获取应用主窗口。
let windowClass: window.Window | null = null;
windowStage.getMainWindow((err: BusinessError, data) => {
let errCode: number = err.code;
if (errCode) {
console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));
return;
}
windowClass = data;
console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));
let sysBarProps: window.SystemBarProperties = {
//无论什么模式设为黑色
statusBarContentColor: '#000000',
};
windowClass.setWindowSystemBarProperties(sysBarProps, (err: BusinessError) => {
let errCode: number = err.code;
if (errCode) {
console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
return;
}
// console.info('Succeeded in setting the system bar properties.');
});
})
//-----启动时设置状态栏文字颜色---结束--
//在设置启动页前设置---
windowStage.loadContent('pages/MainPage'
二、单页面防录屏---输入密码防截屏
这个经常被用在用户登录输入账号密码场景,在这个页面下不可进行手机截屏和录屏,有效的防止了电信诈骗的发生,保障用户信息安全。
ts
static async setScreenCapture(isPrivacyMode: boolean): Promise<void> {
try {
let windowClass: window.Window = await window.getLastWindow(getContext())
let promise = windowClass.setWindowPrivacyMode(isPrivacyMode); // 设置防截屏录屏
promise.then(() => {
console.info(`${isPrivacyMode?'开启':'关闭'}防截屏录屏-成功`);
console.info('Succeeded in setting the window to privacy mode.');
}).catch((err: BusinessError) => {
console.info(`${isPrivacyMode?'开启':'关闭'}防截屏录屏-失败`);
console.error(`ErrorCode: ${err.code}, Message: ${err.message}`);
})
} catch (e) {
console.info(`${isPrivacyMode?'开启':'关闭'}防截屏录屏-异常`);
console.error(`ErrorCode: ${JSON.stringify(e)}, Message: ${e}`)
}
三、应用内工具-跳市场看本APP,跳浏览器更新
这个在应用内的 【当前版本号】并点击检查更新的时候经常用到,之前做的应用客户提出了这个需求,不过笔者近半年都在做鸿蒙元服务项目,基本没用到了,因为元服务的更新是很及时的,没有展现给用户版本号或者检查更新的必要,也没有产品去元服务里加这个功能了。不得不说元服务在跟新版本这块还挺无感的,只要你AGC平台更新版本通过了审核,在你打开元服务的时候他就为新版了,类似与某信小程序
ts
/**
* 应用内打开打开浏览器
*
配置文件添加
"uris": [{
"scheme": "https",
"pathStartWith": "query"
},
{
"scheme": "http"
}]
*/
async openSystemBrowser(url: string) {
if (url) {
try {
let want: Want = {
"action": "ohos.want.action.viewData",
"entities": ["entity.system.browsable"],
"uri": url,
"type": "text/plain"
}
let context = getContext() as common.UIAbilityContext;
await context.startAbility(want)
console.info(`explicit start ability succeed`)
} catch (error) {
console.info(`explicit start ability failed with ${error.code}`)
}
}
}
/**
* 跳转到应用市场,打开自己的应用
*/
async startAppGalleryDetailAbility() {
try {
// 唯一appID
const appID = 'app的bundname'
const context = getContext() as common.UIAbilityContext
const want: Want = {
action: 'ohos.want.action.appdetail',
uri: 'store://appgallery.huawei.com/app/detail?id=C' + appID
}
context.startAbility(want)
} catch (error) {
console.log('Logger ------>', error)
}
}
/**
* 获取当前版本号
*/
getAppInfo() {
const bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
let appInfo: string[] = []
bundleManager.getBundleInfoForSelf(bundleFlags, (err, data) => {
// 获取应用自身的bundleName
const bundleName = data.name;
// 获取应用的版本号(versionCode)
const versionCode = data.versionCode;
// 获取应用的版本名(versionName)
const versionName = data.versionName;
appInfo = [bundleName, versionCode.toString(), versionName]
if (err) {
console.error(`getBundleInfoForSelf failed: ${err.message}`);
return appInfo
} else {
console.info(`get bundleName successfully: ${bundleName}`);
console.info(`get versionCode successfully: ${versionCode}`);
console.info(`get versionName successfully: ${versionName}`);
console.info(`getBundleInfoForSelf successfully: ${JSON.stringify(data)}`);
return appInfo
}
})
}
不过 应用内元服务间跳转还是经常能用到的。可以mark一下凹。
四、去重数组
哈哈对于数组的处理其实我们在上篇已经总结了,欢迎大家查看我的发布记录,可以说数组的常见处理贯穿了每一个应用甚至页面,尤其现在鸿蒙开发主推的是navigation路由,在这种路由模式下的接收路由参数数据,是以数组的方式传来的。简单提一下,如果你也对navigation路由有兴趣,欢迎交流凹,
ts
let cids: string[] = [] //筛选出不重复的cid数组
cids = cidList.filter((item, index, self) => {
return self.indexOf(item) === index
})
[1,2,33,33,2]--->[1,2,33]
既然提到路由了,我记得在2024年初鸿蒙官方还在主推router路由,到9月初就变心了,现在的主推使用navigation,因为这个路由一旦上手了就很好的避免了页面堆栈超标,在新手开发中使用router路由容易习惯性的进入某个页面就pushUrl,导致页面栈超过一定数量而强行退出APP。这个没有具体数字与系统平台和手机性能可能有很大关系,鸿蒙建议不超过16个最多31个应该。
所以我的笔记里也有一条
router.pushUrl的滥用避免
避免一直用pushUrl,在返回时用back及时回来 页面栈超过32时会崩溃 在一些不需要返回的跳转逻辑或者不需要返回当前页的地方可以用replace 所以推荐使用navigate优化路由
五、 鸿蒙自带的加载中组件LoadingProgress的使用
ts
if (this.loading) {
LoadingProgress()
.color($r('app.color.loading_color'))
.width($r('app.float.login_progress_size'))
.height($r('app.float.login_progress_size'))
.margin({ top: $r('app.float.login_progress_margin_top') })
}
这里我们需要注意的是这个控制布尔值的创建与何时开启与关闭逻辑,理清楚就不难了,冷静点
六、屏幕侧滑路由的拦截,用户侧滑手机返回时执行你想要的逻辑
有一说一这个真挺实用的,侧滑屏幕正常返回上一个 页面栈,在有entry修饰的页面,用这个生命函数里设置route就可以拦截侧滑的路由方向了 onBackPress函数一定要返回true才可以实现上一行的路由代码或你的自定义逻辑否则还是默认的back上一层页面栈 相信我会有侧滑返回,不是回到上一个页面栈的需求的,产品大佬的创意总是无线的,而我们只是他的另一个职能上的同事。 当然如果有退出动画的需求,这个也可能用的上凹。
ts
onBackPress() {
router.back({ url: '/pages/目标page'.slice(1) })
return true //想要实现自定义的侧滑返回效果页,这里一定手写true,,,否则会往目标页的前一个页面栈,如无则返回上一个页面栈
}
写在后面
哎呀今天又一次回看了一年前的笔记,很多开发中与同事相处的场景也历历在目,当然也再次熟悉了一些散碎的实战开发知识点,希望对大家开发之路有那么一点帮助。 如果你已经看到这里啦,不仿点个赞吧。