WaterFlow高性能开发指导

Signed-off-by: zzz701 <lihaima1@huawei.com>
WaterFlow高性能开发指导
This commit is contained in:
zzz701 2023-12-28 20:56:30 +08:00
parent e96d7fef46
commit 8ce0c15fbc
30 changed files with 525 additions and 4 deletions

View File

@ -82,6 +82,10 @@ BackgroundTask使用说明
3.点击**长时任务**按钮进入场景页,授予通知权限和定位权限,和点击**开启定位服务**按钮开启定位,点击**关闭定位服务**关闭定位。
WaterFlow使用说明
1.点击性能示例主页的**WaterFlow**按钮,进入**WaterFlow**场景页
### 工程目录
```
@ -154,6 +158,10 @@ features
| | |---BackgroundTaskHomeView.ets // 场景主页面模块
| | |---TransientTaskView.ets // 短时任务页面
| | |---LongTermTaskView.ets // 长时任务页面
---/waterFlow/src/main/ets // waterFlow功能HAR共享包
| |---/pages
| | |---Index.ets // 场景主页面模块
| | |---WaterFlowDataSource.ets // 数据源
products/phone/entry/src/main/ets
|---/entryability
| |---EntryAbility.ts // 封装整个模块启用监听Ability对应的窗口等逻辑
@ -202,7 +210,10 @@ products/phone/entry/src/main/ets
| | |---LongTermTask.ets // 长时任务页面
| |---/trace
| | |---TracePage.ets // 懒加载示例首页
| |---/Index
| |---/Index
| |---/waterFlow
| | |---WaterFlowPage.ets // WaterFlow示例首页
| |---/Index
|---/utils
| |---Logger.ets // 封装整个日志

View File

@ -81,6 +81,26 @@
{
"name": "backgroundTask",
"srcPath": "./feature/backgroundTask"
},
{
"name": "DFXStateManagement",
"srcPath": "./feature/DFXStateManagement"
},
{
"name": "memoryShared",
"srcPath": "./feature/memoryShared",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
},
{
"name": "WaterFlow",
"srcPath": "./feature/WaterFlow"
}
]
}

View File

@ -0,0 +1,6 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { WaterflowDemo } from './src/main/ets/pages/Index'

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
"apiType": "stageMode",
"buildOption": {
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
},
"consumerFiles": [
"./consumer-rules.txt"
]
}
}
},
],
"targets": [
{
"name": "default"
}
]
}

View File

@ -0,0 +1,6 @@
import { harTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

View File

@ -0,0 +1,18 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
"license": "Apache-2.0",
"devDependencies": {},
"author": "",
"name": "waterflow",
"description": "Please describe the basic information.",
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Index.ets
import { WaterFlowDataSource } from './WaterFlowDataSource'
@Reusable
@Component
struct ResuableFlowItem {
@State item: number = 0
// 从复用缓存中加入到组件树之前调用,可在此处更新组件的状态变量以展示正确的内容
aboutToReuse(params: Record<string, number>) {
this.item = params.item;
}
build() {
Column() {
Text("N" + this.item).fontSize(12).height('16')
Image('res/waterFlowTest(' + this.item % 5 + ').jpg')
.objectFit(ImageFit.Fill)
.width('100%')
.layoutWeight(1)
}
}
}
@Component
export struct WaterflowDemo {
@State minSize: number = 200
@State maxSize: number = 400
@State fontSize: number = 24
@State colors: number[] = [0xFFC0CB, 0xDA70D6, 0x6B8E23, 0x6A5ACD, 0x00FFFF, 0x00FF7F]
scroller: Scroller = new Scroller()
datasource: WaterFlowDataSource = new WaterFlowDataSource()
private itemWidthArray: number[] = []
private itemHeightArray: number[] = []
// 计算flow item宽/高
getSize() {
let ret = Math.floor(Math.random() * this.maxSize)
return (ret > this.minSize ? ret : this.minSize)
}
// 保存flow item宽/高
getItemSizeArray() {
for (let i = 0; i < 100; i++) {
this.itemWidthArray.push(this.getSize())
this.itemHeightArray.push(this.getSize())
}
}
aboutToAppear() {
this.getItemSizeArray()
}
@Builder
itemFoot() {
Row() {
LoadingProgress()
.color(Color.Blue).height(50).aspectRatio(1).width('20%')
Text(`正在加载`)
.fontSize(20)
.width('30%')
.height(50)
.align(Alignment.Center)
.margin({ top: 2 })
}.width('100%').justifyContent(FlexAlign.Center)
}
build() {
Column({ space: 2 }) {
WaterFlow() {
LazyForEach(this.datasource, (item: number) => {
FlowItem() {
// 使用可复用自定义组件
ResuableFlowItem({ item: item })
}
.onAppear(() => {
// 即将触底时提前增加数据
if (item + 5 == this.datasource.totalCount()) {
for (let i = 0; i < 20; i++) {
this.datasource.AddLastItem()
}
}
})
.width('100%')
.height(this.itemHeightArray[item % 100])
.backgroundColor(this.colors[item % 5])
}, (item: string) => item)
}
.columnsTemplate("1fr 1fr")
.columnsGap(10)
.rowsGap(5)
.backgroundColor(0xFAEEE0)
.width('100%')
.height('90%')
}.padding(5)
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 实现IDataSource接口的对象用于瀑布流组件加载数据
export class WaterFlowDataSource implements IDataSource {
private dataArray: number[] = []
private listeners: DataChangeListener[] = []
constructor() {
for (let i = 0; i < 100; i++) {
this.dataArray.push(i)
}
}
// 获取索引对应的数据
public getData(index: number): number {
return this.dataArray[index]
}
// 通知控制器数据重新加载
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
})
}
// 通知控制器数据增加
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdded(index)
})
}
// 通知控制器数据变化
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChanged(index)
})
}
// 通知控制器数据删除
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDeleted(index)
})
}
// 通知控制器数据位置变化
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMoved(from, to)
})
}
// 获取数据总数
public totalCount(): number {
return this.dataArray.length
}
// 注册改变数据的控制器
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener)
}
}
// 注销改变数据的控制器
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener)
if (pos >= 0) {
this.listeners.splice(pos, 1)
}
}
// 增加数据
public Add1stItem(): void {
this.dataArray.splice(0, 0, this.dataArray.length)
this.notifyDataAdd(0)
}
// 在数据尾部增加一个元素
public AddLastItem(): void {
this.dataArray.splice(this.dataArray.length, 0, this.dataArray.length)
this.notifyDataAdd(this.dataArray.length - 1)
}
// 在指定索引位置增加一个元素
public AddItem(index: number): void {
this.dataArray.splice(index, 0, this.dataArray.length)
this.notifyDataAdd(index)
}
// 删除第一个元素
public Delete1stItem(): void {
this.dataArray.splice(0, 1)
this.notifyDataDelete(0)
}
// 删除第二个元素
public Delete2ndItem(): void {
this.dataArray.splice(1, 1)
this.notifyDataDelete(1)
}
// 删除最后一个元素
public DeleteLastItem(): void {
this.dataArray.splice(-1, 1)
this.notifyDataDelete(this.dataArray.length)
}
// 重新加载数据
public Reload(): void {
this.dataArray.splice(1, 1)
this.dataArray.splice(3, 2)
this.notifyDataReload()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
"module": {
"name": "WaterFlow",
"type": "har",
"deviceTypes": [
"default",
"tablet"
]
}
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}

View File

@ -24,12 +24,14 @@
"@ohos/backgroundTask": "file:../../../feature/backgroundTask",
"@ohos/grid": "file:../../../feature/grid",
"@ohos/smartPerfHost": "file:../../../feature/smartPerfHost",
"@ohos/WaterFlow": "file:../../../feature/WaterFlow",
"@ohos/staticImport": "file:../../../feature/staticImport",
"@ohos/DFXStateManagement": "file:../../../feature/DFXStateManagement",
"@ohos/ifOrVisibility": "file:../../../feature/ifOrVisibility",
"@ohos/dynamicImport": "file:../../../feature/dynamicImport",
"@ohos/smartPerfEditor": "file:../../../feature/smartPerfEditor",
"@ohos/hiDumper": "file:../../../feature/hiDumper",
"@ohos/memoryShared": "file:../../../feature/memoryShared",
"@ohos/trace": "file:../../../feature/trace",
"@ohos/backgroundTask": "file:../../../feature/backgroundTask"
"@ohos/hiDumper": "file:../../../feature/hiDumper"
}
}

View File

@ -51,5 +51,17 @@ export let performanceTypeArray: Array<PerformanceMsg> = [
{
name: 'BackgroundTask',
uri: 'pages/backgroundTask/BackgroundTaskPage'
},
{
name: 'MemoryShared',
uri: 'pages/memoryShared/MemorySharedHomePage'
},
{
name: 'DFX StateManagement',
uri: 'pages/DFXStateManagement/DFXStateManagementPage'
},
{
name: 'WaterFlow',
uri: 'pages/waterFlow/WaterFlowPage'
}
]

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { WaterflowDemo } from '@ohos/WaterFlow';
@Entry
@Component
struct TracePage {
build() {
Column() {
WaterflowDemo()
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

View File

@ -32,6 +32,13 @@
"pages/trace/TracePage",
"pages/backgroundTask/BackgroundTaskPage",
"pages/backgroundTask/TransientTask",
"pages/backgroundTask/LongTermTask"
"pages/backgroundTask/LongTermTask",
"pages/waterFlow/WaterFlowPage",
"pages/memoryShared/MemorySharedHomePage",
"pages/memoryShared/AtomicsUsagePage",
"pages/memoryShared/LockUsagePage",
"pages/DFXStateManagement/DFXStateManagementPage",
"pages/DFXStateManagement/DFXStateBeforeOptimizationPage",
"pages/DFXStateManagement/DFXStateAfterOptimizationPage"
]
}

View File

@ -618,5 +618,30 @@ export default function abilityTest() {
Logger.info(TAG, `${BUNDLE}BackgroundTask_001 end`);
done();
})
/**
* WaterFlow高性能开发指导
*/
it(BUNDLE + "WaterFlow_001", 1, async (done: Function) => {
Logger.info(TAG, `${BUNDLE}WaterFlow_001 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(500);
await driver.swipe(10, 800, 10, 100, 600);
// 点击进入WaterFlow的使用首页
let waterBtn: Component = await driver.findComponent(ON.text('WaterFlow'));
await driver.delayMs(500);
await waterBtn.click();
await driver.delayMs(500);
// 滑动页面 循环连续向上滑动4次
for (let index = 0; index < 4; index++) {
await driver.swipe(10, 1000, 10, 0, 15000);
}
// 退出到首页面
await driver.delayMs(500);
await driver.pressBack();
Logger.info(TAG, `${BUNDLE}WaterFlow_001 end`);
done();
})
})
}