限定範圍儲存空間

範圍儲存限制應用程式對外部儲存的存取。在 Android 11 或更高版本中,面向 API 30 或更高版本的應用程式必須使用分區儲存。以前在 Android 10 中,應用程式可以選擇退出範圍儲存。

應用程式存取限制

範圍儲存的目標是保護應用程式和用戶資料的隱私。這包括保護使用者資訊(例如相片元資料)、防止應用程式在未經明確許可的情況下修改或刪除使用者文件,以及保護下載到「下載」或其他資料夾的敏感使用者文件。

使用範圍儲存的應用程式可以具有以下存取等級(實際存取權限特定於實作)。

  • 無權限讀寫自己的文件
  • 使用READ_EXTERNAL_STORAGE權限讀取其他應用程式的媒體文件
  • 僅在使用者直接同意的情況下才允許對其他應用程式的媒體檔案進行寫入存取(授予系統庫和有資格存取所有檔案的應用程式的例外)
  • 無法讀取寫入其他應用程式的外部應用程式資料目錄

將範圍儲存與 FUSE 結合使用

Android 11 或更高版本支援使用者空間中的檔案系統 (FUSE),這使得 MediaProvider 模組能夠檢查使用者空間中的檔案操作,並根據允許拒絕編輯存取的策略來控制對檔案的存取。作用域儲存中使用 FUSE 的應用程式可以獲得作用域儲存的隱私功能以及使用直接檔案路徑存取檔案的能力(保持檔案 API 在應用程式中運行)。

Android 10 對 MediaProvider 的檔案存取強制執行範圍儲存規則,但由於攔截核心呼叫所需的工作量,因此不適用於直接檔案路徑存取(例如,使用檔案 API 和 NDK API)。因此,作用域儲存中的應用程式無法使用直接檔案路徑存取檔案。此限制影響了應用程式開發人員的適應能力,因為它需要大量程式碼變更才能重寫 File API 對 MediaProvider API 的存取。

保險絲和SD卡FS

Android 11 對 FUSE 的支援與SDCardFS 的棄用無關,但確實為先前使用 SDCardFS 的裝置提供了媒體儲存的替代方案。裝置:

  • 使用核心 5.4 或更高版本啟動 Android 11 或更高版本無法使用 SDCardFS。
  • 升級到 Android 11 或更高版本可以在 SDCardFS 之上託管 FUSE,以攔截檔案操作並滿足隱私目標。

FUSE 效能調整

Android 之前在 Android 7 或更低版本中支援 FUSE,其中外部儲存被掛載為 FUSE。由於 FUSE 實現的效能和死鎖問題,Android 8 引入了 SDCardFS。 Android 11 使用經過改進、經過更好測試的libfuse實作重新引入了對 FUSE 的支持,可以對其進行調整以解決 Android 7 或更低版本中的效能問題。

FUSE 調整包含以下調整:

  • 繞過Android/dataAndroid/obb目錄的 FUSE,以提高依賴這些目錄的遊戲應用程式的效能。
  • 最佳化(例如調整 FUSE 檔案系統的預讀率和髒率)以保持讀取效能和媒體播放流暢。
  • 使用 FUSE 回寫式快取。
  • 快取權限,減少系統伺服器的IPC。
  • 優化具有所有文件存取權限的應用程序,使批次操作更快。

上述調整調整可在 FUSE 和非 FUSE 裝置之間產生可比較的效能。例如,使用 FUSE 測試經過調整的 Pixel 2 和使用 Media Store 測試的 Pixel 2 發現檔案路徑存取和 Media Store 之間的順序讀取效能(例如視訊播放)相當。然而,使用 FUSE 時順序寫入的速度稍差,隨機讀取和寫入的速度可能會慢兩倍。

效能測量可能會因設備和特定用例的不同而有所不同。由於 MediaProvider API 可提供最一致的效能,因此關心效能的應用程式開發人員應在其應用程式中使用 MediaProvider API。

減輕 FUSE 效能影響

FUSE 效能影響僅限於外部共用儲存體上儲存的檔案的大量使用者。外部私有儲存(包括android/dataandroid/obb目錄)會被 FUSE 繞過,而內部儲存(例如/data/data ,許多應用程式在其中儲存資料以保持資料加密和安全性)未安裝 FUSE。

  • 少量使用共享外部儲存的應用程式通常會與一組有限的檔案(通常少於 100 個檔案)進行互動。這些應用程式受益於常見讀取和寫入操作的現有最佳化,並且在 Android 11 中不會出現任何與 FUSE 相關的效能影響。

  • 大量使用共用外部儲存的應用程式通常會執行批次檔案操作,例如列出或刪除包含 1000 個檔案的目錄,或在檔案系統上建立或刪除包含 100 萬個檔案的目錄。批次檔案操作可能會受到 Android 11 上 FUSE 的影響,但如果此類應用程式符合MANAGE_EXTERNAL_STORAGE權限,它們將受益於 2020 年 10 月更新中包含的性​​能優化。

為了避免 FUSE 效能開銷,應用程式可以將資料儲存在外部私有儲存中,或使用ContentProvider類別中的批次 API 來繞過 FUSE 並獲得效能最佳化的路徑。此外,MediaProvider 系統元件的 2020 年 10 月更新包括對檔案管理器和持有MANAGE_EXTERNAL_STORAGE權限的類似應用程式(例如備份/復原、防毒)的效能最佳化。

隱私高於效能

在已針對FUSE 進行調優的裝置上,大多數關鍵使用者旅程在Android 10 和Android 11 之間的效能相同。但是,在測試一組檔案操作的基準時,Android 11 的效能可能比Android 10 差。對於執行以下操作的檔案存取模式:在 Android 11 中情況更糟(例如隨機讀取或寫入),我們建議使用 MediaProvider API 為應用程式提供非 FUSE 存取模式,這是最佳且效能一致的選項。

MediaProvider 和 FUSE 更新

MediaProvider系統元件的行為因 Android 版本而異。

  • 在 Android 10 及更低版本中,SDCardFS 是檔案系統,MediaProvider 提供檔案集合(例如影像、影片、音樂檔案等)的介面。當應用程式使用檔案 API 建立檔案時,它可以要求 MediaProvider 掃描檔案並將其記錄在資料庫中。

  • 在 Android 11 或更高版本中, SDCardFS已棄用,MediaProvider 成為外部儲存的檔案系統處理程序(對於 FUSE),使外部儲存上的檔案系統和 MediaProvider 資料庫保持一致。作為 FUSE 檔案系統的使用者空間處理程序,MediaProvider 可以攔截核心呼叫並確保檔案操作的隱私安全。

在 Android 11 及更高版本中,MediaProvider 也是一個模組化系統元件(主線模組),可在 Android 版本之外進行更新。這意味著 MediaProvider 中發現的效能、隱私或安全性問題可以透過 Google Play 商店或其他合作夥伴提供的機制透過無線方式進行修復和交付。 FUSE 處理程序預期範圍內的任何內容也是可更新的,從而能夠透過更新來修復 FUSE 效能回歸和錯誤。