回复
#HarmonyOS NEXT体验官#手把手教你自定义装饰器实现Android中的Lifecycle组件 原创
冉冉同学
发布于 2024-8-1 11:06
浏览
0收藏
1. 背景
在鸿蒙实际开发中,为了防止内存泄露我们有以下写法。需要手动在aboutToDisappear 中反注册,或者执行一段逻辑。此时我们会有点怀念Android JetPack中的Lifecycle 组件。
1.1 事件订阅-页面关闭取消监听键盘高度变化
import { Utils } from '@android/utilcode'
@Component
struct Test {
private onKeyboardHeightChange = (height: number) => {
//键盘高度变化
console.log(`键盘高度${height}`)
}
/**
* 注册键盘高度监听
*/
aboutToAppear() {
Utils.getMainWindow()?.on('keyboardHeightChange', this.onKeyboardHeightChange)
}
//取消注册键盘高度监听
aboutToDisappear(): void {
Utils.getMainWindow()?.off('keyboardHeightChange', this.onKeyboardHeightChange)
}
build() {
}
}
1.2 网络请求-页面关闭取消未完成的网络请求
import { rcp } from "@kit.RemoteCommunicationKit";
import { BusinessError } from '@kit.BasicServicesKit';
@Component
struct Test {
private session?: rcp.Session;
build() {
Button('发起网络请求').onClick(() => {
this.session = rcp.createSession();
this.session.get("https://wanandroid.com/harmony/index/json").then((response) => {
console.info(`${response}`);
}).catch((err: BusinessError) => {
console.error(`err: err code is ${err.code}, err message is ${err.message}`);
});
})
}
//取消未完成的网络请求
aboutToDisappear(): void {
this.session?.cancel()
this.session?.close()
}
}
2. 使用TS自定义装饰器封装 Lifecycle
2.1 先创建一个生命周期管理类Lifecycle.ets
import { ArrayList } from '@kit.ArkTS';
/**
* 生命周期状态
* @author Tanranran
* @date 2024/6/5 23:45
* @description
*/
export enum LifecycleState {
ToAppear,
PageShow,
PageHide,
ToDisappear,
}
/**
* 生命周期包装类
* @author Tanranran
* @date 2024/6/5 23:45
* @description
*/
export class Lifecycle {
private mObserverList: ArrayList<(state: LifecycleState) => void> | null = new ArrayList();
/**
* @Component
* 组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
*/
aboutToAppear() {
this.dispatchEvent(LifecycleState.ToAppear)
}
/**
* @Entry
* 页面每次显示时触发一次,包括路由过程、应用进入前台等场景。
*/
onPageShow() {
this.dispatchEvent(LifecycleState.PageShow)
}
/**
* @Entry
* 页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
*/
onPageHide() {
this.dispatchEvent(LifecycleState.PageHide)
}
/**
* @Component
* aboutToDisappear函数在自定义组件析构销毁之前执行
*/
aboutToDisappear() {
this.dispatchEvent(LifecycleState.ToDisappear)
}
/**
* 向所有观察者分发状态
* @param state
*/
private dispatchEvent(state: LifecycleState) {
this.mObserverList?.forEach((callback: (state: LifecycleState) => void) => {
callback(state)
});
}
/**
* 添加观察者
* @param callback
*/
addObserver(callback: (state: LifecycleState) => void) {
this.mObserverList?.add(callback)
}
/**
* 移除观察者
* @param callback
*/
removeObserver(callback: (state: LifecycleState) => void) {
this.mObserverList?.remove(callback)
}
/**
* 释放所有观察者
*/
release() {
this.mObserverList?.clear()
this.mObserverList = null
}
}
2.2 再创建一个和组件生命周期绑定的自定义装饰类 LifecycleEvent.ts
export function LifecycleEvent(target: any, propertyKey: string | any) {
let value: any;
const getter = () => value;
const setter = function (newValue: any) {
value = newValue;
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true,
});
if (target.rerender) {
if (target.aboutToAppear) {
let oldFunction = target.aboutToAppear
function appear() {
oldFunction.call(this)
target[propertyKey].aboutToAppear()
}
target.aboutToAppear = appear
} else {
target.aboutToAppear = () => {
target[propertyKey].aboutToAppear()
}
}
if (target.onPageShow) {
let oldFunction = target.onPageShow
function pageShow() {
target[propertyKey].onPageShow()
oldFunction.call(this)
}
target.onPageShow = pageShow
} else {
target.onPageShow = () => {
target[propertyKey].onPageShow()
}
}
if (target.onPageHide) {
let oldFunction = target.onPageHide
function pageHide() {
target[propertyKey].onPageHide()
oldFunction.call(this)
}
target.onPageHide = pageHide
} else {
target.onPageHide = () => {
target[propertyKey].onPageHide()
}
}
if (target.aboutToDisappear) {
let oldFunction = target.aboutToDisappear
function disappear() {
target[propertyKey].aboutToDisappear()
target[propertyKey].release()
oldFunction.call(disappear.prototype.caller)
}
target.aboutToDisappear = disappear
} else {
target.aboutToDisappear = () => {
target[propertyKey].aboutToDisappear()
target[propertyKey].release()
}
}
}
}
3.使用TS自定义装饰器封装,自动取消页面中未完成的网络请求
@LifecycleEvent 声明的Lifecycle 会自动绑定@Component 的aboutToDisappear 生命周期,当组件销毁时,会回调 Lifecycle.ets 中的mObserverList集合。所有注册了addObserver 的监听均会收到生命周期变化的回调
3.1 封装和页面生命周期绑定的网络请求帮助类
import { rcp } from "@kit.RemoteCommunicationKit";
import { Lifecycle } from '@android/utilcode';
import { LifecycleState } from '@android/utilcode/src/main/ets/lifecycle/Lifecycle';
/**
* @author Tanranran
* @date 2024/6/17 17:48
* @description
*/
export class HttpHelper {
static Get(url: string, lifecycle: Lifecycle):Promise<rcp.Response>{
let session = rcp.createSession();
lifecycle.addObserver((state: LifecycleState) => {
if (state == LifecycleState.ToDisappear) {
session.cancel()
session.close()
}
})
return session.get(url);
}
}
3.2 使用带有生命周期绑定的网络请求帮助类
import { HttpHelper } from './HttpHelper';
import { Lifecycle, LifecycleEvent } from '@android/utilcode';
@Component
struct Test {
@LifecycleEvent lifecycle: Lifecycle = new Lifecycle()
build() {
Button('发起网络请求').onClick(() => {
HttpHelper.Get('https://wanandroid.com/harmony/index/json', this.lifecycle)
})
}
}
4. 如果想用现成的可以直接使用远程库
https://ohpm.openharmony.cn/#/cn/detail/@android%2Futilcode
自定义组件生命周期绑定装饰器,可通过以下方式自动绑定自定义组件的生命周期,使用方法和Android中的Lifecycle类似 无需关注lifecycle的释放,自定义组件aboutToDisappear时,lifecycle会自动释放
使用场景:比如页面关闭后,当前页面上的未请求完毕网络请求自动取消
注:目前仅支持aboutToAppear【Component】、onPageShow【Entry】、onPageHide【Entry】、aboutToDisappear【Component】,navigation 比较特殊,目前暂未找到合适的时机
import {Lifecycle, LifecycleEvent } from '@android/utilcode';
@Component
@Preview
export struct TestFragment {
@LifecycleEvent lifecycle: Lifecycle = new Lifecycle()
aboutToAppear(): void {
this.lifecycle.addObserver((state: LifecycleState) => {
//此处即可
console.log("状态" + state)
})
}
}
5. 另外分享一篇关于鸿蒙状态管理装饰器的实现的文章
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
赞
收藏
回复
相关推荐