Android 應用開發 | 一種限制拷貝速率解決因 IO 過高導致系統卡頓的方法

文章目錄

  • 一、問題背景
  • 二、代碼實現

一、問題背景

經常做 Android 應用的小伙伴應該會有經驗,就是如果應用在寫入文件的時候,即使寫文件的動作是在子線程,也會出現 UI 上的卡頓,這是因為文件的 IO 是由內核去完成的,此時 CPU 會從 用戶態 切換到 內核態,應用將無法獲得 CPU 時間片。如果 IO 較少的時候,這個切換不頻繁,應用能有足夠的時間片去執行繪制。但如果 IO 頻繁,例如高速寫入的場景下,此時 IO 占用的時間片增加,而我們知道 CPU 資源是有限的,此時會導致應用獲得 時間片 將減少,導致 UI 繪制線程出現卡頓,進而影響 UI 上的卡頓。

我們可以使用 top 命令,查看 IO 占用 CPU 的時間片(即 iow):
在這里插入圖片描述

因此,如果不能從其它方式去解決此問題(內核層的 IO 調度 和 CPU 調度機制),可以運用簡單的方式:在寫入文件的時候,限制寫入速度,減緩 IO 占用率。

二、代碼實現

例如,一個標準的拷貝文件的 Kotlin 方法如下:

originFile.inputStream().buffered().use { inputStream ->targetFile.outputStream().buffered().use { outputStream ->val buffer = ByteArray(1024)var bytesRead: Intwhile (inputStream.read(buffer).also { bytesRead = it } != -1) {outputStream.write(buffer, 0, bytesRead)}outputStream.flush()}
}

這個方法對 源文件 開啟了 InputStream,并轉換為 BufferInputStream,而對 目標文件 開啟了 OutputStream,并轉換為 BufferOutputStream,然后再從 InputStream 讀取流,輸出到 OutputStream,完成文件的讀寫。

而我們為了實現限制其寫入速度,我們可以定義一個速率,例如每秒寫入 20M,即每秒寫入的字節數為 20 * 1024 * 1024 = 20, 971, 520 。在每次寫入量達到 20M 的時候,檢查一次寫入這 20M 使用的時長,如果這個時長 < 1s ,則表示在這 1s 的時間里,寫入的速率已經超過了 20M,需要等待一定時長,使其滿足 1s 內只寫入 20M 的需求。代碼如下:

// 限制拷貝時的速率, 每秒最多拷貝的字節數
val MAX_COPY_SPEED = 20 * 1024 * 1024L// 記錄已拷貝的文件大小
var copiedSize = 0L// 記錄上次檢查性能的時間 (用來計算拷貝速率 限制拷貝速率)
var lastCheckPerformanceTime = System.currentTimeMillis()
// 記錄上次檢查時 已拷貝的數據量
var lastCheckPerformanceSize = 0LoriginFile.inputStream().buffered(1024 * 1024).use { inputStream ->targetFile.outputStream().buffered().use { outputStream ->val buffer = ByteArray(DEFAULT_BUFFER_SIZE)var bytesRead: Intwhile (inputStream.read(buffer).also { bytesRead = it } != -1) {outputStream.write(buffer, 0, bytesRead)// 增加已拷貝文件的大小copiedSize += bytesRead// 計算拷貝速率 每滿 MAX_COPY_SPEED 計算一次速率if (copiedSize - lastCheckPerformanceSize >= MAX_COPY_SPEED) {lastCheckPerformanceSize = copiedSizeval time = System.currentTimeMillis()// 計算寫入 MAX_COPY_SPEED 字節數所使用的時間val deltaTime = time - lastCheckPerformanceTimelastCheckPerformanceTime = time// 如果速率大于 MAX_COPY_SPEED 則暫停 等待下次計算if (deltaTime < 1000) {// 延遲 1000 - deltaTime 使滿足 1s 內只寫入指定量delay(1000 - deltaTime)}}}outputStream.flush()}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88120.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88120.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88120.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

力扣面試150(19/150)

7.7 12. 整數轉羅馬數字 七個不同的符號代表羅馬數字&#xff0c;其值如下&#xff1a; 符號值I1V5X10L50C100D500M1000 羅馬數字是通過添加從最高到最低的小數位值的轉換而形成的。將小數位值轉換為羅馬數字有以下規則&#xff1a; 如果該值不是以 4 或 9 開頭&#xff0c;…

數據結構與算法——從遞歸入手一維動態規劃【1】

前言&#xff1a; 簡單記錄對左程云系列算法課程--算法講解066【必備】的學習&#xff0c;這是第一篇。主要提供C代碼和一些簡單的個人理解&#xff0c;如需要細致講解請移步原視頻。 涉及內容&#xff1a; 斐波那契數列、動態規劃 參考視頻&#xff1a; 左程云--算法講解…

搭建個人博客系列--Nacos 注冊中心

基礎項目已完成&#xff0c;接下來就是SpringCloud的各種組件了。 那你又要問&#xff1a;既然有Nacos為什么之前還裝了Apollo&#xff1f; 那你別管&#xff0c;那不得什么都會點&#xff0c;不然怎么找工作。干就完了。 一、安裝Nacos 管他三七二十一&#xff0c;先在doc…

前端實習總結——案例與大綱

以下是一個結合真實場景的前端面試案例&#xff0c;包含面試流程、核心問題、候選人回答思路及面試官考察點&#xff0c;可直觀感受如何在面試中展現實習/項目經歷&#xff1a; 案例背景 候選人&#xff1a;應屆生&#xff0c;有6個月前端實習經歷&#xff0c;參與過“企業內部…

Web前端開發: :where(偽類函數選擇器)

:where(偽類函數選擇器)&#xff1a;:where() 是 CSS Selectors Level 4 規范中引入的一個強大的偽類函數選擇器&#xff0c;它允許開發者以簡潔的方式編寫復雜的選擇器&#xff0c;同時具有獨特的優先級特性。核心概念&#xff1a;:where() 偽類函數選擇器與 :is() 非常相似&a…

EfficientVMamba: Atrous Selective Scan for Light Weight Visual Mamba論文精讀(逐段解析)

EfficientVMamba: Atrous Selective Scan for Light Weight Visual Mamba論文精讀&#xff08;逐段解析&#xff09; 論文地址&#xff1a;https://arxiv.org/abs/2403.09977 CVPR 2024 Abstract. Prior efforts in light-weight model development mainly centered on CNN an…

Integer緩沖區

文章目錄常見面試題&#xff1a;總結Integer緩沖區是Java預先創建的一個固定范圍的Integer對象緩存池&#xff08;默認-128到127&#xff09;&#xff0c;用于自動復用頻繁使用的整數值&#xff0c;減少內存開銷和對象創建。當通過自動裝箱或Integer.valueOf()生成該范圍內的整…

[國家電網備考]計算機網絡

計算機網絡的概述 概念: 用通信設備與線路將地理位置不同,功能獨立的計算機系統互連起來,以功能完善的網絡軟件實現網絡中資源共享和信息傳遞的系統 自治計算機: 能夠自我管理,配置,維護的計算機(目前我們使用的電腦) 以前的終端只有顯示器,不能叫做自治計算機 計算機網絡向用戶…

在 Linux(openEuler 24.03 LTS-SP1)上安裝 Kubernetes + KubeSphere 的防火墻放行全攻略

目錄 在 Linux&#xff08;openEuler 24.03 LTS-SP1&#xff09;上安裝 Kubernetes KubeSphere 的防火墻放行全攻略 一、為什么要先搞定防火墻&#xff1f; 二、目標環境 三、需放行的端口和協議列表 四、核心工具說明 1. 修正后的 exec.sh 腳本&#xff08;支持管道/重…

HTTP 響應頭信息詳解

HTTP 響應頭信息詳解 引言 HTTP(超文本傳輸協議)是互聯網上應用最為廣泛的網絡協議之一。在HTTP協議中,響應頭信息是服務器向客戶端發送的重要信息之一。響應頭信息包含了關于響應的元數據,如狀態碼、內容類型、緩存策略等。本文將詳細介紹HTTP響應頭信息的概念、類型、作…

去掉長按遙控器power鍵后提示關機、飛行模式的彈窗

首先找到對應長短按power鍵的位置&#xff1a;frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.javaprivate final Runnable mPowerLongPress new Runnable() {Overridepublic void run() {// The context isnt readif (mLongPressOnPowerBe…

Redis-哨兵機制Sentinel

redis的主從復制模式下,一旦主節點出現了故障無法提供服務了,需要人工進行主從切換,同時大量的客戶端需要被通知切換到新的主節點上,對于有了一定規模的應用來說,這種方案的延遲是無法接受的,于是redis2.8提供了Redis-Sentinel(哨兵)來解決這個問題. 目錄 1.啥是哨兵節點: 2.r…

SQL 視圖

SQL 視圖 引言 SQL 視圖是數據庫管理系統中的一種重要概念,它允許用戶以不同的方式查看數據庫中的數據。本文將詳細介紹 SQL 視圖的概念、作用、創建方法以及在實際應用中的注意事項。 一、SQL 視圖的概念 SQL 視圖是數據庫中的一種虛擬表,它并不存儲實際的數據,而是基于…

ESP32-使用VSCODE 各種問題總結匯總

1 問題 1 1.1 具體問題描述-config:idf.customExtraPath 無法正確描述launch.json 中使用了一個變量&#xff1a; ${config:idf.customExtraPaths}但在 VSCode 的設置中&#xff0c;并沒有找到對應的設置項 idf.customExtraPaths&#xff0c;所以無法解析。 1.2 問題解決 1.2.1…

【剪裁Patch】已標注的WSI剪裁Patch的處理流程(以QuPath軟件得到的標注信息為例)

1. 整體處理思路 整體處理流程如圖所示,概括來說就是:根據標注信息將WSI區分為腫瘤區域和正常區域,對這個區域進行采樣裁剪得到具有Patch級別標簽的Patch。 當然,這里的Patch標簽是根據標注信息決定的,如果標注的是癌癥亞型信息,那么也可以將不同亞型的Patch區分出來。 …

Qt 與Halcon聯合開發九:算法類設計與實現講解(附源碼)

一、設計背景 在機器視覺系統中&#xff0c;算法是系統的核心。不同產品、不同項目對圖像處理的要求不盡相同&#xff0c;因此算法需要具備&#xff1a; 靈活拓展&#xff1a;方便添加新算法統一調用&#xff1a;界面或上層邏輯不關心算法細節結構清晰&#xff1a;便于維護與…

npu-driver 23.0.3驅動安裝

宿主機器上安裝npu-driver/ npu-firmware這兩個東西 wget -O Ascend-hdk-910b-npu-driver_23.0.3_linux-aarch64.run https://bj.bcebos.com/v1/aipe-easyedge-public/cann/eb_speed/Ascend-hdk-910b-npu-driver_23.0.3_linux-aarch64.run?authorizationbce-auth-v1%2F50c8bb…

LeetCode題解---<三數之和>

文章目錄題目<三數之和>--Python解法題解題目<三數之和>–Python解法 給你一個整數數組 nums &#xff0c;判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i ! j、i ! k 且 j ! k &#xff0c;同時還滿足 nums[i] nums[j] nums[k] 0 。請你返回所有和為…

探索Insplorion氫氣傳感器:高靈敏度與快速響應的創新解決方案

在追求更清潔、更安全能源的過程中&#xff0c;氫氣作為一種理想的清潔能源載體&#xff0c;正日益受到全球的重視。然而&#xff0c;氫氣的廣泛應用也帶來了新的挑戰——如何確保其儲存、運輸和使用的安全性&#xff1f;Insplorion通過其獨特的納米等離子體傳感&#xff08;NP…

【QT】事件(鼠標、按鍵、定時器、窗口)

文章目錄1. 事件1.1 事件的介紹1.2 事件的處理2. 按鍵事件3. 鼠標事件4. 定時器5. 窗口事件1. 事件 1.1 事件的介紹 事件是應用程序內部或者外部產生的事情或者動作的統稱。 在 Qt 中使用?個對象來表示?個事件。所有的 Qt 事件均繼承于抽象類 QEvent。事件是由系統或者 Qt …