範圍存儲限制了應用對外部存儲的訪問。在Android 11或更高版本中,定位到API 30或更高版本的應用必須使用作用域存儲。以前在Android 10中,應用可能會選擇退出範圍存儲。
應用程序訪問限制
範圍存儲的目標是保護應用程序和用戶數據的隱私。這包括保護用戶信息(例如照片元數據),防止應用程序未經明確許可而修改或刪除用戶文件以及保護下載到“下載”或其他文件夾的敏感用戶文檔。
使用範圍存儲的應用程序可以具有以下訪問級別(實際訪問特定於實現)。
- 讀取和寫入訪問自己的文件沒有權限
- 具有
READ_EXTERNAL_STORAGE
權限的讀取對其他應用程序媒體文件的READ_EXTERNAL_STORAGE
權限 - 僅在用戶直接同意的情況下,才允許對其他應用程序的媒體文件進行寫訪問(授予System Gallery和有資格使用“所有文件”訪問的應用程序的例外)
- 沒有讀或寫訪問其他應用的外部應用程序數據目錄
將範圍存儲與FUSE一起使用
Android 11或更高版本支持用戶空間中的文件系統(FUSE),該功能使MediaProvider模塊可以檢查用戶空間中的文件操作,並根據允許,拒絕或編輯訪問的策略來控制對文件的訪問。作用域存儲中使用FUSE的應用程序具有作用域存儲的隱私功能,並具有使用直接文件路徑訪問文件的能力(保持文件API在應用程序中運行)。
Android 10對MediaProvider的文件訪問實施了強製作用域存儲規則,但由於攔截內核調用需要付出很大的努力,因此不能用於直接文件路徑訪問(例如,使用File API和NDK API)。結果,作用域存儲中的應用無法使用直接文件路徑訪問文件。此限制影響了應用程序開發人員的適應能力,因為它需要進行實質性的代碼更改以重寫File API對MediaProvider API的訪問。
保險絲和SDCardFS
Android 11對FUSE的支持與SDCardFS的棄用無關,但確實為以前使用SDCardFS的設備提供了Media Store的替代方法。設備:
- 使用內核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/data
和Android/obb
目錄繞過FUSE,以提高依賴於這些目錄的遊戲應用程序的性能。 - 優化(例如調整FUSE文件系統的預讀率和臟率),以保持讀取性能和媒體播放流暢。
- 使用FUSE寫回緩存。
- 緩存權限以減少對系統服務器的IPC。
- 針對具有“所有文件”訪問權限的應用程序進行了優化,以加快批量操作的速度。
上述調整可以在FUSE和非FUSE設備之間產生可比的性能。例如,使用FUSE測試調優的Pixel 2和使用Media Store測試Pixel 2,發現在文件路徑訪問和Media Store之間可比較的順序讀取性能(例如,視頻播放)。但是,使用FUSE時,順序寫入的性能會稍差一些,而隨機讀取和寫入的速度可能會慢兩倍。
性能度量可以在不同設備之間以及特定用例之間變化。因為MediaProvider API提供了最一致的性能,所以關注性能的應用程序開發人員應為其應用程序使用MediaProvider API。
減輕FUSE性能的影響
FUSE性能影響僅限於大量用戶使用外部共享存儲中存儲的文件。 FUSE繞過了外部私有存儲(包括android/data
和android/obb
目錄),而內部存儲(例如/data/data
,其中許多應用程序存儲數據以使其保持加密和安全)沒有FUSE安裝。
共享外部存儲的輕度用戶的應用程序經常與一組有限的文件(通常少於100個文件)進行交互。這些應用程序受益於常見讀寫操作的現有優化,並且不會在Android 11中看到任何與FUSE相關的性能影響。
大量使用共享外部存儲的應用通常會執行批量文件操作,例如列出或刪除具有1000個文件的目錄,或者在文件系統上創建或刪除具有一百萬個文件的目錄。批量文件操作可能會受到Android 11上FUSE的影響,但是如果此類應用程序符合
MANAGE_EXTERNAL_STORAGE
權限,則它們將從2020年10月更新中包括的性能優化中受益。
為了避免FUSE性能開銷,應用程序可以將數據存儲在外部私有存儲中,或使用ContentProvider
類中的批量API繞過FUSE並獲得性能優化的路徑。此外,2020年10月對MediaProvider系統組件的更新還包括對文件管理器和具有MANAGE_EXTERNAL_STORAGE
權限的類似應用程序(例如備份/還原,防病毒)的性能優化。
超越性能的隱私
在針對FUSE進行了調整的設備上,大多數關鍵的用戶體驗在Android 10和Android 11之間的性能均相同。但是,在對一組文件操作進行基準測試時,Android 11的性能可能會比Android 10差。更糟糕的是,在Android 11中(例如,隨機讀取或寫入),我們建議使用MediaProvider API為應用程序提供非FUSE訪問模式,這是最佳且始終如一的性能選擇。
MediaProvider和FUSE更新
在不同的Android版本之間, MediaProvider系統組件的行為有所不同。
在Android 10及更低版本中,SDCardFS是文件系統,MediaProvider提供了文件集合的接口(例如,圖像,視頻,音樂文件等)。當應用程序使用File API創建文件時,它可能會要求MediaProvider掃描文件並將其記錄在數據庫中。
在Android 11或更高版本中,不建議使用SDCardFS ,MediaProvider成為用於外部存儲的文件系統處理程序(用於FUSE),從而使外部存儲上的文件系統與MediaProvider數據庫保持一致。作為FUSE文件系統的用戶空間處理程序,MediaProvider可以攔截內核調用,並確保文件操作是隱私安全的。
在Android 11及更高版本中,MediaProvider還是一個模塊化系統組件(Mainline模塊),可以在Android版本之外進行更新。這意味著可以解決MediaProvider中發現的性能,隱私或安全問題,並通過Google Play商店或其他合作夥伴提供的機制通過廣播進行廣播。 FUSE處理程序所期望的範圍內的任何內容也是可更新的,從而可以進行更新以修復FUSE性能下降和錯誤。