HarmonyOS 鸿蒙Next 在Promise中读取远程数据并写入文件,通过callback回调进度刷新UI的问题:@State数据变化不立即刷新UI
HarmonyOS 鸿蒙Next 在Promise中读取远程数据并写入文件,通过callback回调进度刷新UI的问题:@State数据变化不立即刷新UI 在Promise中,读取远程数据并写入到文件,通过callback回调进度从而刷新UI。但是@State对应的数据有变化,UI并不会立即刷新
export class DownloadViewModel {
downloadCallback:(progress:number)=>void =()=>{}
download(){
let promise: Promise<number> = new Promise((resolve: Function, reject: Function) => {
let sessionId = 0
if (sessionId < 0) {
//回调进度 失败
reject()
return
}
this.isDownloadingFile = true
this.downloadFileTimeOutId = setTimeout(() => {
if (!this.isDownloadingFile) {
return
}
if (this.rdtId >= 0) {
cameraNapi.RDT_Destroy(this.rdtId)
this.rdtId = -1
}
this.rdtId = cameraNapi.RDT_Create(sessionId, this.RDT_TIME_OUT, this.uploadOrDownloadChannelID)
try {
if (this.rdtId >= 0 && this.isDownloadingFile) {
let sendRDTCommand = new Uint8Array(128)
sendRDTCommand[0] = RDCTRLDEFs.RDT_COMMAND_FILE_NAME.valueOf()
let name = Uint8ArrayUtils.strToUint8Array(path)
sendRDTCommand.set(name, 1)
let result = cameraNapi.RDT_Write(this.rdtId, sendRDTCommand)
this.log("downloadFile RDT_Write result=" + result)
if (result >= 0 && this.rdtId >= 0) {
let recvBuffer = new Uint8Array(1024)
result = cameraNapi.RDT_Read(this.rdtId, recvBuffer, this.RDT_TIME_OUT)
this.log("downloadFile RDT_Read result=" + result)
if (result > 0) {
this.log("downloadFile RDT_Read type=" + recvBuffer[0])
if (recvBuffer[0] == RDCTRLDEFs.RDT_COMMAND_FILE_SIZE.valueOf()) {
let sizeArray = Packet.uint8ArrayToUint8Array(recvBuffer, 1, 8)
let fileTotalSize = Number(Uint8ArrayUtils.uint8ArrayToStr(sizeArray))
this.log("downloadFile fileSize=" + fileTotalSize)
let startContent = this.getRDTSendFileContent(RDCTRLDEFs.RDT_COMMAND_FILE_START.valueOf(), "Start")
result = cameraNapi.RDT_Write(this.rdtId, startContent)
this.log("downloadFile start send result=" + result)
if (result >= 0) {
let status: RDT_Status = {
Timeout: 0,
TimeoutThreshold: 0,
BufSizeInSendQueue: 0,
BufSizeInRecvQueue: 0
}
let check = cameraNapi.RDT_Status_Check(this.rdtId, status)
if (check >= 0) {
let readTotal = 0
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
this.saveFile = fs.openSync(savePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
let writeOptions: WriteOptions = {
length: 1024
}
this.downloadCallback(0)
let lastProgress = 0
do {
let recvBuffer = new Uint8Array(1024)
// recvBuffer.fill(0)
result = cameraNapi.RDT_Read(this.rdtId, recvBuffer, this.RDT_TIME_OUT)
this.log("download read length=" + result)
if (result > 0) {
writeOptions.length = result
//内容写入文件
fs.write(this.saveFile.fd, recvBuffer.buffer, writeOptions)
readTotal += result
writeOptions.offset = readTotal
let progress = Math.floor(readTotal / fileTotalSize * 100)
if(lastProgress != progress){
this.downloadCallback(progress)
}
} else {
break
}
} while (this.isDownloadingFile && readTotal < fileTotalSize && this.rdtId >= 0)
let progress = Math.floor(readTotal / fileTotalSize * 100)
this.downloadCallback(progress)
// this.uploadOrDownloadProgress(path, 0, progress, 1)
resolve(1)
}
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
} else {
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
reject()
}
let endContent = this.getRDTSendFileContent(RDCTRLDEFs.RDT_COMMAND_FILE_STOP, "Stop")
cameraNapi.RDT_Write(this.rdtId, endContent)
} else {
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
reject()
}
} else {
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
reject()
}
} else {
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
reject()
}
} else {
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
reject()
}
} catch (e) {
if (this.saveFile) {
fs.closeSync(this.saveFile)
this.saveFile = undefined
}
reject()
}
if (this.rdtId >= 0) {
cameraNapi.RDT_Destroy(this.rdtId)
this.rdtId = -1
}
this.stopDownload()
}, 500)
})
return promise
}
}
@Component
export struct DownloadPage{
[@State](/user/State) progress:number = 0
private downloadViewModel:DownloadViewModel = new DownloadViewModel()
private download(){
this.downloadViewModel.downloadCallback = (progress:number)=>{
this.progress = progress
}
}
build() {
Column(){
Progress({
value:this.progress
})
Button("下载")
.onClick(()=>{
this.download()
})
}
}
}
更多关于HarmonyOS 鸿蒙Next 在Promise中读取远程数据并写入文件,通过callback回调进度刷新UI的问题:@State数据变化不立即刷新UI的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next 在Promise中读取远程数据并写入文件,通过callback回调进度刷新UI的问题:@State数据变化不立即刷新UI的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,如果在Promise中读取远程数据并写入文件,同时希望通过callback回调来刷新UI,但遇到@State
数据变化不立即刷新UI的问题,通常这是因为UI刷新依赖于系统的事件循环机制。在异步操作中,UI刷新可能会被延迟,直到当前事件循环结束。
要解决这个问题,你可以考虑以下几种方法:
-
使用
@ObservedObject
或@EnvironmentObject
:这些属性包装器可以确保对象在数据变化时自动通知UI进行刷新。 -
调度到主线程:确保UI更新操作在主线程执行。HarmonyOS可能提供类似SwiftUI的
DispatchQueue.main.async
的方法,用于将更新操作调度到主线程。 -
利用
ObjectWillChange
:手动触发对象的变化通知。在你的数据模型中,可以调用objectWillChange.send()
来通知视图刷新。 -
检查数据绑定:确保你的数据绑定正确无误,
@State
变量确实与UI组件相关联。
如果上述方法仍然无法解决问题,可能是由于特定的实现细节或系统限制。此时,建议深入检查你的代码逻辑,或者查阅HarmonyOS的官方文档以获取更多关于异步UI更新的指导。如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html,