HarmonyOS 鸿蒙Next Taskpool字符串宽度计算与性能影响 HarmonyOS 鸿蒙Next TaskGroup大量执行时是否影响UI主线程性能 HarmonyOS 鸿蒙Next 模拟器执行execute并操作UI卡顿崩溃问题
HarmonyOS 鸿蒙Next Taskpool字符串宽度计算与性能影响
HarmonyOS 鸿蒙Next TaskGroup大量执行时是否影响UI主线程性能
HarmonyOS 鸿蒙Next 模拟器执行execute并操作UI卡顿崩溃问题
小说章节数据加载时会进入HandleTaskPool这个函数,按批次每批batchSize:100个章节的字符串数据进入batchTaskPool函数进行多线程taskpool处理,不清楚重复改变taskGroup1会不会有影响。最终数据处理成this.AllChaptersContent
taskpool.execute处理数据的时候进行UI操作,比如改变当前章节,模拟器会卡顿,将batchSize缩小改成10也会有崩溃的情况
//Canvas多线程方案,按字拆分,taskpool多线程处理
import { chaptersItem } from 'ets/componets/dataList/ReaderChaptersItem';
import { taskpool } from '@kit.ArkTS';
@Component
export struct TxtContentHandler {
@Prop @Watch('HandleTaskPool') txtFile: chaptersItem[] = [];
@Prop @Watch('CurrentChaptersChange') CurrentChapters: number = 0;
@Prop @Watch('CurrentFontSizeChange') CurrentFontSize: number = 0;
@Prop LineHeight: number = 1.8; // 百分比
@Prop ParagraphSpacing: number = 0;
@Prop ReaderPadding: number = 0;
@State AllChaptersContent: Array<string>[] = []; // 存放需要显示在页面上每个章节重排段落的字符串,一层数组索引为章节,二层数组索引为段落
@State tempAllChaptersContent: Array<string>[] = [];
@State lines: string[] = [];
@State currentPage: number = 0;
@State ShowHeight: number = 0
@State @Watch('HandleTaskPool') ShowWidth: number = 0
@State linesPerPage: number = 0;
@State isChangeTimer: number = 0;
@State isTaskPoolHandleNumber: number = 0;
@State SleepTime: number = 0;
@State innerSleepTime: number = 0;
@State timer: number = 0;
@State taskGroup1: taskpool.TaskGroup = new taskpool.TaskGroup();
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
// 获取总页数
GetTotalPages() {
return Math.floor(this.AllChaptersContent[this.CurrentChapters]?.length / this.linesPerPage);
}
async batchTaskPool(batchStart: number, batchSize: number) {
this.taskGroup1 = new taskpool.TaskGroup();
for (let i = batchStart; i < Math.min(batchStart + batchSize, this.txtFile.length); i++) {
let dataArray: Array<string> = [
this.txtFile[i].content,
this.CurrentFontSize.toString(),
this.ShowWidth.toString(),
]
let task: taskpool.Task = new taskpool.Task(HandleAllChaptersContentTaskPool, dataArray);
this.taskGroup1.addTask(task);
}
return taskpool.execute(this.taskGroup1, taskpool.Priority.LOW).then(res => {
for (let i = 0; i < res.length; i++) {
this.AllChaptersContent[batchStart+i] = res[i] as Array<string>;
}
}).catch(error => {
console.error(`taskpool excute error: ${error}`);
})
}
Sleep(ms: number, str: string): Promise<void> {
return new Promise(resolve => {
this.SleepTime = setTimeout(resolve, ms)
})
}
// 多线程处理
async HandleTaskPool() {
this.isTaskPoolHandleNumber++ // 多次调节字体大小或者其它时,防止重复渲染
let NowTaskPoolHandleNumber = this.isTaskPoolHandleNumber // 同上,只有最新isTaskPoolHandleNumber才可以进入下面判定
await this.Sleep(2000, 'out') // 控制任务执行间隔,这个数字尽量调大一点,如果调太小,会导致两个taskpool同时处理
if (this.txtFile.length > 0 && this.ShowWidth > 0 && NowTaskPoolHandleNumber == this.isTaskPoolHandleNumber) {
// 需要txt文件加载和showWidth同时准备好,且是最新的isTaskPoolHandleNumber,才进入处理数据并渲染,
console.log('TaskPoolHandleNumber:' + NowTaskPoolHandleNumber)
let NowChapters = this.CurrentChapters
const batchSize = 100; // 每批次处理的任务数量,爆内存就调小
for (let batchStart = NowChapters; batchStart < this.txtFile.length; batchStart += batchSize) {
// 优先处理当前章节数据,并渲染到页面上
if (NowTaskPoolHandleNumber == this.isTaskPoolHandleNumber) {
let taskpoolInfo: taskpool.TaskPoolInfo = taskpool.getTaskPoolInfo();
console.log('threadInfos:' + JSON.stringify(taskpoolInfo.threadInfos))
this.drawPage() // 页面渲染函数
await this.batchTaskPool(batchStart, batchSize)
console.log('batchStartTaskpool done:' + Math.min(batchStart + batchSize, this.txtFile.length));
} else {
// 只处理最新的文字,旧的直接退出,防止重复处理
break
}
}
if (NowChapters > 0) {
// 如果当前章节不为0,前面的章节要补上
for (let batchStart = 0; batchStart < NowChapters; batchStart += batchSize) {
if (NowTaskPoolHandleNumber == this.isTaskPoolHandleNumber) {
await this.batchTaskPool(batchStart, batchSize)
console.log('batchStartTaskpool done:' + Math.min(batchStart + batchSize, this.txtFile.length));
} else {
// 只处理最新的文字,旧的直接退出,防止重复处理
break
}
}
}
if (NowTaskPoolHandleNumber == this.isTaskPoolHandleNumber) {
if (this.tempAllChaptersContent.length > 0) {
this.AllChaptersContent = this.tempAllChaptersContent
}
this.drawPage();
console.log('taskpool handle finish')
this.isTaskPoolHandleNumber = 0
} else {
console.log(`${NowTaskPoolHandleNumber} AllBreak`)
}
}
}
async CurrentChaptersChange() {
this.currentPage = 0
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.drawPage();
console.log('CurrentChapters:' + this.CurrentChapters)
console.log('currentPage:' + this.currentPage)
console.log('totalPages:' + this.GetTotalPages())
}, 100)
}
CurrentFontSizeChange() {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
console.log('CurrentFontSize:' + this.CurrentFontSize)
this.drawPage();
this.HandleTaskPool()
}, 100)
}
drawPage() {
// 页面渲染函数,渲染到canvas上
this.context.font = `${vp2px(this.CurrentFontSize)}px`;
this.linesPerPage = Math.floor((this.ShowHeight) / (this.CurrentFontSize * this.LineHeight));
if (this.context && this.AllChaptersContent[this.CurrentChapters]) {
this.context.font = `${vp2px(this.CurrentFontSize)}px`;
this.context.fillStyle = 'black';
const start = this.currentPage * this.linesPerPage;
const end = start + this.linesPerPage;
const pageLines = this.AllChaptersContent[this.CurrentChapters].slice(start, end);
this.context.clearRect(0, 0, this.ShowWidth, this.ShowHeight);
pageLines.forEach((line, index) => {
this.context.fillText(line, 0, (index + 1) * this.CurrentFontSize * Number(this.LineHeight));
});
}
}
nextPage() {
if (this.currentPage < this.GetTotalPages()) {
this.currentPage++;
console.log('currentPage:' + this.currentPage + '\ntotalPages:' + this.GetTotalPages())
this.drawPage();
}
}
prevPage() {
if (this.currentPage > 0) {
this.currentPage--;
console.log('prevPage:' + this.currentPage)
this.drawPage();
}
}
build() {
Column() {
Canvas(this.context)
.layoutWeight(1)
.onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => {
this.ShowHeight = Number(newValue.height)
this.ShowWidth = Number(newValue.width)
this.drawPage()
this.HandleTaskPool()
console.log('currentPage:' + this.currentPage + '\ntotalPages:' + this.GetTotalPages())
console.log('ShowHeight:' + this.ShowHeight)
console.log('ShowWidth:' + this.ShowWidth)
console.log('currentPage:' + this.currentPage + '\ntotalPages:' + this.GetTotalPages())
})
Row() {
Button('上一页')
.onClick(() => {
this.prevPage()
})
.backgroundColor(this.currentPage > 0 ? 'blue' : 'gray')
Button('下一页')
.onClick(() => {
this.nextPage()
})
.backgroundColor(this.currentPage < this.GetTotalPages() ? 'blue' : 'gray')
}
.borderWidth(1)
.margin({ top: 10 })
}
}
}
@Concurrent
function HandleAllChaptersContentTaskPool(dataArray: Array<string>) {
let content: string = dataArray[0]
let CurrentFontSize = Number(dataArray[1])
let ShowWidth = Number(dataArray[2])
let chaptersItemLines: string[] = []
let currentLine: string = ''
let pattern = /\n/
let i = 1
while (i < content.length) {
let temp = content[i] + content[i+1]
if (!pattern.test(temp)) {
if (Number(currentLine.length + 1) * CurrentFontSize < Number((ShowWidth - 10).toFixed(0))) {
currentLine += content[i];
} else {
chaptersItemLines.push(currentLine);
currentLine = content[i];
}
i++
} else {
chaptersItemLines.push(currentLine);
i = i + 2
currentLine = content[i];
}
}
if (pattern.test(chaptersItemLines[chaptersItemLines.length-1])) {
chaptersItemLines.splice(chaptersItemLines.length - 1, 1)
}
return chaptersItemLines
}
更多关于HarmonyOS 鸿蒙Next Taskpool字符串宽度计算与性能影响 HarmonyOS 鸿蒙Next TaskGroup大量执行时是否影响UI主线程性能 HarmonyOS 鸿蒙Next 模拟器执行execute并操作UI卡顿崩溃问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
使用真机试试
更多关于HarmonyOS 鸿蒙Next Taskpool字符串宽度计算与性能影响 HarmonyOS 鸿蒙Next TaskGroup大量执行时是否影响UI主线程性能 HarmonyOS 鸿蒙Next 模拟器执行execute并操作UI卡顿崩溃问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
HarmonyOS 鸿蒙Next Taskpool字符串宽度计算与性能影响
在HarmonyOS中,Taskpool用于管理并发任务。字符串宽度计算若频繁进行且任务繁重,可能会影响性能。优化建议包括减少不必要的计算、利用缓存机制存储常用结果,或采用异步处理方式来减轻主线程负担。
HarmonyOS 鸿蒙Next TaskGroup大量执行时是否影响UI主线程性能
TaskGroup用于管理一组并发或顺序执行的任务。大量执行时,若未合理管理任务优先级和调度,可能会抢占UI主线程资源,导致性能下降。建议合理划分任务,使用低优先级队列处理非UI相关任务,确保UI线程流畅运行。
HarmonyOS 鸿蒙Next 模拟器执行execute并操作UI卡顿崩溃问题
模拟器执行execute
时操作UI出现卡顿或崩溃,可能由于多线程同步问题或资源竞争导致。确保UI操作在主线程进行,使用任务队列或信号量机制同步多线程访问UI资源。此外,检查代码中的内存泄漏和无效引用,避免资源耗尽导致崩溃。
如果问题依旧没法解决请联系官网客服, 官网地址是 https://www.itying.com/category-93-b0.html,