了解 Android 應(yīng)用的文件存儲(chǔ)目錄,掌握持久化數(shù)據(jù)的正確姿勢簡書 · 亦楓 · · 打開原文 本文導(dǎo)讀:在安卓手機(jī)上,安裝或者卸載一個(gè) App,會(huì)涉及到本地存儲(chǔ)系統(tǒng)的哪些目錄結(jié)構(gòu)變化?作為開發(fā)人員,如何恰當(dāng)?shù)卮鎯?chǔ)應(yīng)用相關(guān)的信息? ![]() 本文導(dǎo)讀:在安卓手機(jī)上,安裝或者卸載一個(gè) App,會(huì)涉及到本地存儲(chǔ)系統(tǒng)的哪些目錄結(jié)構(gòu)變化?作為開發(fā)人員,如何恰當(dāng)?shù)卮鎯?chǔ)應(yīng)用相關(guān)的信息?相關(guān)存儲(chǔ)目錄的生命周期、訪問方式和訪問權(quán)限又是怎樣的呢?帶著這些問題,希望讀完這篇文章,你能夠有所收獲。 內(nèi)部存儲(chǔ)空間中的應(yīng)用私有目錄對于設(shè)備中每一個(gè)安裝的 App,系統(tǒng)都會(huì)在內(nèi)部存儲(chǔ)空間的 data/data 目錄下以應(yīng)用包名為名字自動(dòng)創(chuàng)建與之對應(yīng)的文件夾。這個(gè)文件夾用于 App 中的 WebView 緩存頁面信息,SharedPreferences 和 SQLiteDatabase 持久化應(yīng)用相關(guān)數(shù)據(jù)等。 對于沒有 Root 過的手機(jī),普通用戶是無法查看 data/data 目錄內(nèi)容的。不過開發(fā)人員可以使用模擬器調(diào)試應(yīng)用,并通過 DDMS(Dalvik Debug Monitor Server)提供的 File Explorer 工具查看模擬器設(shè)備的存儲(chǔ)空間。 ![]() 操作路徑: 第一步:Android Studio --> Tools --> Android --> Android Device Monitor; 第二步:Window --> Show View --> Android --> File Explorer。 Android SDK 提供有如下方法可以獲取并操作內(nèi)部存儲(chǔ)空間下應(yīng)用私有目錄文件的方,都位于 Application Context 中,供開發(fā)者直接調(diào)用:
等等,也可以通過 Environment 類訪問: Environment.getDataDirectory(); 注意:當(dāng)用戶卸載 App 時(shí),系統(tǒng)自動(dòng)刪除 data/data 目錄下對應(yīng)包名的文件夾及其內(nèi)容。 外部存儲(chǔ)空間中的應(yīng)用私有目錄考慮內(nèi)部存儲(chǔ)空間容量有限,普通用戶不能直接直觀地查看目錄文件等其他原因,Android 在外部存儲(chǔ)空間中也提供有特殊目錄供應(yīng)用存放私有文件,文件路徑為: /storage/emulated/0/Android/data/app package name 備注:一般設(shè)備都有內(nèi)置 SD 卡,同時(shí)也提供外部 SD 卡拓展,可能對應(yīng)路徑的目錄名有所差異。 值得注意的是,與內(nèi)部存儲(chǔ)空間的應(yīng)用私有目錄不同的是: 第一,默認(rèn)情況下,系統(tǒng)并不會(huì)自動(dòng)創(chuàng)建外部存儲(chǔ)空間的應(yīng)用私有目錄。只有在應(yīng)用需要的時(shí)候,開發(fā)人員通過 SDK 提供的 API 創(chuàng)建該目錄文件夾和操作文件夾內(nèi)容。 第二,自 Android 7.0 開始,系統(tǒng)對應(yīng)用私有目錄的訪問權(quán)限進(jìn)一步限制。其他 App 無法通過 file:// 這種形式的 Uri 直接讀寫該目錄下的文件內(nèi)容,而是通過 FileProvider 訪問。(關(guān)于這個(gè)內(nèi)容,接下來再寫一篇文章專門說說 7.0 的適配問題,歡迎關(guān)注我的微信公眾號:安卓筆記俠。) 第三,宿主 App 可以直接讀寫內(nèi)部存儲(chǔ)空間中的應(yīng)用私有目錄;而在 4.4 版本開始,宿主 App 才可以直接讀寫外部存儲(chǔ)空間中的應(yīng)用私有目錄,使開發(fā)人員無需在 Manifest 文件中或者動(dòng)態(tài)申請外部存儲(chǔ)空間的文件讀寫權(quán)限。 而相同點(diǎn)在于:同屬于應(yīng)用私有目錄,當(dāng)用戶卸載 App 時(shí),系統(tǒng)也會(huì)自動(dòng)刪除外部存儲(chǔ)空間下的對應(yīng) App 私有目錄文件夾及其內(nèi)容。 同樣,Android SDK 中也提供有便捷的 API 供開發(fā)人員直接操作外部存儲(chǔ)空間下的應(yīng)用私有目錄:
等等,當(dāng)然,也可以通過 Environment 類間接操作,只不過需要向用戶申請操作權(quán)限: Environment.getExternalStorageDirectory(); 類似于 File 和 Cache 默認(rèn)分類目錄,開發(fā)人員也可以在應(yīng)用私有目錄中創(chuàng)建屬于自己的自定義目錄,方便于分類存儲(chǔ)應(yīng)用相關(guān)文件。 值得注意的一點(diǎn)是,對于外部存儲(chǔ)空間下的應(yīng)用私有目錄文件,由于普通用戶可以自由修改和刪除,開發(fā)人員在使用時(shí),一定要做好判空處理和異常捕獲,防止應(yīng)用崩潰退出! 外部存儲(chǔ)空間中的公共目錄通常來說,應(yīng)用涉及到的持久化數(shù)據(jù)分為兩類:應(yīng)用相關(guān)數(shù)據(jù)和應(yīng)用無關(guān)數(shù)據(jù)。前者是指專供宿主 App 使用的數(shù)據(jù)信息,比如一些應(yīng)用的配置信息,數(shù)據(jù)庫信息,緩存文件等。當(dāng)應(yīng)用被卸載,這些信息也應(yīng)該被隨之刪除,避免存儲(chǔ)空間產(chǎn)生不必要的占用。 相對而言,后者更偏向于這類信息:當(dāng)應(yīng)用被卸載,用戶仍然希望保留于設(shè)備當(dāng)中的信息。常見如,拍照類應(yīng)用的圖片文件,用戶是使用瀏覽器手動(dòng)下載的文件等。 顯然,無論是內(nèi)部存儲(chǔ)空間,還是外部儲(chǔ)存空間,上述兩個(gè)應(yīng)用私有目錄由于其特有的生命周期(隨著應(yīng)用卸載而自動(dòng)清除)只適合存儲(chǔ)應(yīng)用相關(guān)數(shù)據(jù)。 或者從訪問權(quán)限上來說,應(yīng)用無關(guān)數(shù)據(jù)應(yīng)該是宿主應(yīng)用希望與其他應(yīng)用共享這些數(shù)據(jù)的,應(yīng)該存放在外部存儲(chǔ)空間的公共目錄文件夾下。 外部存儲(chǔ)空間已經(jīng)為用戶默認(rèn)分類出一些公共目錄。開發(fā)人員可以通過 Environment 類提供的方法直接獲取相應(yīng)目錄的絕對路徑,傳遞不同的 type 參數(shù)類型即可: Environment.getExternalStoragePublicDirectory(String type); Envinonment 類提供諸多 type 參數(shù)的常量,比如:
等等,以第一個(gè)常量為例,音樂類別的公共目錄絕對路徑為:/storage/emulated/0/Music。如果你使用文件管理器打開設(shè)備的外部存儲(chǔ)空間的話,均可以看到這些公共目錄文件夾。 面對如此諸多的默認(rèn)類別,開發(fā)人員在保存自己應(yīng)用的公共文件時(shí),也要養(yǎng)成良好的習(xí)慣,將要保存的數(shù)據(jù)分門別類地保存在不同公共目錄下。當(dāng)然,你也可以在公共目錄下再次創(chuàng)建屬于自己應(yīng)用的目錄,便于管理。 注意:訪問外部存儲(chǔ)空間時(shí)記得申請讀寫權(quán)限! 外部存儲(chǔ)空間中的其他目錄一般來說,利用兩種應(yīng)用私有目錄和公共目錄便能夠存儲(chǔ)應(yīng)用中需要保存的數(shù)據(jù)和文件。如果這些還不夠的話,那一定是你的開發(fā)姿勢不對。在 Code Review 的前提下,如果還是不夠的話,還可以在外部存儲(chǔ)空間自由創(chuàng)建其他目錄,通過這個(gè)方式獲取外部存儲(chǔ)空間的絕對路徑,然后操作文件: Environment.getExternalStorageDirectory(); 小結(jié)使用應(yīng)用私有目錄保存應(yīng)用相關(guān)數(shù)據(jù),使用公共目錄保存應(yīng)用無關(guān)數(shù)據(jù)(共享數(shù)據(jù))。無論哪種情況,都需要做好數(shù)據(jù)分類保存,便于清除等統(tǒng)一管理。隨便打開手機(jī)上的幾個(gè)應(yīng)用,不難發(fā)現(xiàn),很多應(yīng)用都包含一個(gè)清理緩存的功能。事實(shí)上,開發(fā)人員清理的就是應(yīng)用相關(guān)數(shù)據(jù),也就是應(yīng)用私有目錄下的文件。 考慮到外部存儲(chǔ)空間上的內(nèi)容可能被用戶手動(dòng)刪除,或者卸載拓展 SD 卡等不可控因素,操作前記得使用 Environment 類提供的 API 方法判斷容量是否充足、文件是否存在等情況,做好異常捕獲,減少應(yīng)用崩潰率。相信這一定是一個(gè)良好的習(xí)慣。 更多存儲(chǔ)選項(xiàng)和存儲(chǔ)框架,參考開發(fā)者官網(wǎng): |
|
|