HarmonyOS使用@ohos.request文件下载操作后持有大量header中设入的字符串数据未释放

@ohos.reques downloadFile文件下载操作,通过在header中设置相应字符串,下载完成之后这些header的字符串一直被长期持有,下载执行的次数越多,被保留的字符串数据就越多。通过hidebug.dumpJsHeapData 虚拟机堆导出,查看到的结果。

HarmonyOS使用@ohos.request文件下载操作后持有大量header中设入的字符串数据未释放-鸿蒙开发者社区

代码如下:

import fs from '@ohos.file.fs'; 
import hidebug from '@ohos.hidebug'; 
import request from '@ohos.request'; 
import { BusinessError } from '@kit.BasicServicesKit'; 
@Entry 
@Component 
struct Index { 
  scroller: Scroller = new Scroller() 
  @State status: string | number = '' 
  @State message: string = '' 
  @State performanceTiming: string = ''; 
  @State filename: string = 'blue.jpg' 
  @State progress: string = '' 
  @State downloadProgress: number = 0 
  @State uploadProgress: number = 0 
  @State showUrl: string = ''; 
  @State connectTimeout: number = 0; 
  @State readTimeout: number = 0; 
  @State startTime: number = 0; 
  @State endTime: number = 0; 
  @State maxBodyLength: number = -1; 
  @State maxContentLength: number = -1; 
  controller: TextInputController = new TextInputController() 
  aboutToAppear(): void { 
    AppStorage.setOrCreate("KEY_ENVIRONMENT","abc"); 
  } 
  build() { 
    Scroll(this.scroller) { 
      Column() { 
        //请求按钮 
        Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, wrap: FlexWrap.Wrap }) { 
          Button('下载').width(100).margin({ 
            bottom: 10, 
            right: 10 
          }).onClick((e) => { 
            this.download() 
          }) 
          Button('dump').width(100).margin({ 
            bottom: 10, 
            right: 10 
          }).onClick((e) => { 
            hidebug.dumpJsHeapData('dump_prev_chapter_' + Date.now()) 
          }) 
        } 
        //请求结果 
        Column() { 
          Text('请求结果') 
            .fontSize(18) 
            .fontWeight(FontWeight.Bold) 
            .margin({ bottom: 10 }) 
            .textAlign(TextAlign.Start) 
          Text('下载进度') 
          Progress({ value: this.downloadProgress, type: ProgressType.Linear }) 
            .color('#009BE8').width('100%') 
            .margin({ top: 8, right: 10 }) 
            .style({ strokeWidth: 10 }) 
          // 展示请求内容 
          Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, }) { 
            Text("请求开始时间: " + this.startTime) 
              .width('100%') 
              .fontSize(16) 
              .fontWeight(700) 
              .fontColor('#000000') 
            Text("请求结束时间: " + this.endTime) 
              .width('100%') 
              .fontSize(16) 
              .fontWeight(700) 
              .fontColor('#000000') 
            Text("请求响应时间: " + (this.endTime - this.startTime)) 
              .width('100%') 
              .fontSize(16) 
              .fontWeight(700) 
              .fontColor('#000000') 
            Text("Status: " + this.status) 
              .width('100%') 
              .fontSize(16) 
              .fontWeight(700) 
              .fontColor('#000000') 
            Text("performanceTiming: " + this.performanceTiming) 
              .width('100%') 
              .fontSize(16) 
              .fontWeight(700) 
              .fontColor('#000000') 
            Text("Data: " + this.message) 
              .width('100%') 
              .fontSize(16) 
              .fontWeight(700) 
              .fontColor('#000000') 
              .maxLines(7) 
          } 
          .width('100%') 
          .padding({ top: 20, bottom: 20, right: 15, left: 10 }) 
          .margin({ right: 10 }) 
          .borderStyle(BorderStyle.Solid) 
          .borderWidth(1) 
          .borderColor('#E6E7E8') 
        } 
        .margin({ top: 10, bottom: 20 }) 
        .alignItems(HorizontalAlign.Start) 
 
        Button('清空输入框内容').width(120).onClick((e) => { 
          this.clear() 
        }) 
      } 
    } 
    .scrollable(ScrollDirection.Vertical) // 滚动方向纵向 
    .scrollBar(BarState.On) // 滚动条常驻显示 
    .margin({ left: 10, right: 10 }) 
  } 
  // 下载 
  download() { 
    this.clear() 
    let filePath = getContext(this).cacheDir + '/blue.jpg' 
    // 下载。如果文件已存在,则先删除文件。 
    try { 
      fs.accessSync(filePath); 
      fs.unlinkSync(filePath); 
    } catch (err) { 
    } 
    let downloadTask: request.DownloadTask; 
    try { 
      let header: ESObject = { 
        'content-type': 'text/plain' 
      } 
      let config : ESObject= { 
        headers: header 
      } 
      request.downloadFile(getContext(), { 
        url: 'http://1xx9.9xx.xxx.99:30xxx00/tpc/download/blue.jpg', 
        filePath: filePath, 
        header:createHttpRequestConfig_test<ESObject>(config).headers 
      }, (err: BusinessError, data: request.DownloadTask) => { 
        if (err) { 
          console.error(`[axios] Failed to request the download. Code: ${err.code}, message: ${err.message}`); 
          return; 
        } 
        downloadTask = data; 
        // 下载失败 
        downloadTask.on('fail',  (err)=> { 
          console.info('[axios] ' + JSON.stringify(err)) 
        }); 
        // 完成下载 
        downloadTask.on('complete', () => { 
          console.info('[axios] complete' ) 
          this.message = 'complete' 
        }) 
        downloadTask.on('progress', (loaded, total) => { 
          this.progress = Math.round(loaded/total * 100) + '%' 
          console.info('[axios] progress, loaded=' + loaded + ', total= ' + total ) 
        }) 
      }); 
    } catch (err) { 
      console.error(`[axios]Failed to request the download. err: ${JSON.stringify(err)}`); 
    } 
  } 
  clear() { 
    this.performanceTiming = ''; 
    this.uploadProgress = 0; 
    this.downloadProgress = 0 
    this.message = ''; 
    this.status = ''; 
    this.startTime = 0; 
    this.endTime = 0; 
  } 
} 
export function createHttpRequestConfig_test<D>(config: ESObject) : ESObject { 
  let encryptQdInfoStr = "111111aaaaabbbbccccddddeeeefffgggghhhh111111aaaaabbbbccccddddeeeefffgggghhhh111111" 
  // config.headers.set('QDInfo', encryptQdInfoStr,true) 
  // config.headers.set('Cookie', getCookies(encryptQdInfoStr),true) 
  config.headers['QDInfo'] = encryptQdInfoStr 
  config.headers['Cookie'] =  getCookies(encryptQdInfoStr) 
  return config 
} 
function getCookies(encryptQDInfo:string) : string { 
  let instance = QDNetWorkEnvironment.getInstance().getAppInfoModel(); 
  let cookieStr:string = '' 
  cookieStr += 'appId=xx' 
  cookieStr += '; ' 
  cookieStr += 'areaId=yy' 
  cookieStr += '; ' 
  cookieStr += 'lang=cn' 
  cookieStr += '; ' 
  cookieStr += 'mode=normal' 
  cookieStr += '; ' 
  cookieStr += 'bar=104' 
  cookieStr += '; ' 
  cookieStr += 'qid='+instance 
  cookieStr += '; ' 
  return cookieStr 
} 
export class QDNetWorkEnvironment { 
  private static instance: QDNetWorkEnvironment; 
  private constructor() { 
    // 私有构造函数,防止外部实例化 
  } 
  public static getInstance(): QDNetWorkEnvironment { 
    if (!QDNetWorkEnvironment.instance) { 
      QDNetWorkEnvironment.instance = new QDNetWorkEnvironment(); 
    } 
    return QDNetWorkEnvironment.instance; 
  } 
  public getAppInfoModel(): string | undefined { 
    let appInfo:string | undefined = AppStorage.get("KEY_ENVIRONMENT"); 
    return appInfo 
  } 
}
HarmonyOS
2024-09-06 11:49:49
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zbw_apple

header 里面字符串的生命周期和 downloadTask 绑定,可以考虑在任务完成或失败时调用 delete 接口移除该任务对象。

参考文档:delete

分享
微博
QQ
微信
回复
2024-09-06 15:12:37
相关问题
使用request下载文件方式
118浏览 • 1回复 待解决
检查字符串是否以给定字符串结尾
150浏览 • 1回复 待解决
检查字符串是否以给定字符串开头
179浏览 • 1回复 待解决
HarmonyOS字符串替换问题
199浏览 • 1回复 待解决
HarmonyOS $r 字符串替换问题
173浏览 • 1回复 待解决
HarmonyOS 如何遍历包含emoji字符串
105浏览 • 1回复 待解决
如何将文件转换成字符串
181浏览 • 1回复 待解决
如何生成UUID字符串
1888浏览 • 1回复 待解决
如何加载字符串形式H5数据
1842浏览 • 1回复 待解决
HarmonyOS 字符串怎么手动加换行?
94浏览 • 1回复 待解决