前言前兩天因為開發(fā)一個app更新的功能,我將從服務(wù)器下載的apk文件放在了內(nèi)部存儲目錄(測試手機為小米,路徑為:data/user/0/packagename/files)下面,然后安裝的時候一直安裝不了,提示解析包出錯。后來查詢發(fā)現(xiàn),安裝apk是調(diào)用了PackageInstaller,沒有相關(guān)權(quán)限,這個無法獲取內(nèi)部路徑,所以會安裝不了。借機也復(fù)習(xí)了一遍Android下面存儲相關(guān)的知識點,總結(jié)一番。 存儲分類對于Android存儲目錄,我總結(jié)成一張思維導(dǎo)圖。上面這張圖很清楚的展示了Android存儲的目錄,接下來我們詳細分析每一個目錄。
內(nèi)部存儲位于系統(tǒng)中很特殊的一個位置,對于設(shè)備中每一個安裝的 App,系統(tǒng)都會在 data/data/packagename/xxx 自動創(chuàng)建與之對應(yīng)的文件夾。如果你想將文件存儲于內(nèi)部存儲中,那么文件默認(rèn)只能被你的應(yīng)用訪問到,且一個應(yīng)用所創(chuàng)建的所有文件都在和應(yīng)用包名相同的目錄下。也就是說應(yīng)用創(chuàng)建于內(nèi)部存儲的文件,與這個應(yīng)用是關(guān)聯(lián)起來的。當(dāng)一個應(yīng)用卸載之后,內(nèi)部存儲中的這些文件也被刪除。對于這個內(nèi)部目錄,用戶是無法訪問的,除非獲取root權(quán)限。
一般情況下,我們獲取到的路徑為data/data/packagename/xxx,小米手機下面打印出來的結(jié)果如下: 對于內(nèi)部存儲路徑,我們一般通過以下兩種方式獲取,內(nèi)部存儲空間的獲取都需要使用Context: context.getFileDir() 對應(yīng)內(nèi)部存儲的路徑為: data/data/packagename/files,但是對于有的手機如:華為,小米等獲取到的路徑為:data/user/0/packagename/files context.getCacheDir() 對應(yīng)內(nèi)部存儲的路徑為: data/data/packagename/cache,但是對于有的手機如:華為,小米等獲取到的路徑為:data/user/0/packagename/cache應(yīng)用程序的緩存目錄,該目錄內(nèi)的文件在設(shè)備內(nèi)存不足時會優(yōu)先被刪除掉,所以存放在這里的文件是沒有任何保障的,可能會隨時丟掉。
針對于外部存儲比較容易混淆,因為在Android4.4以前,手機機身存儲就叫內(nèi)部存儲,插入的SD卡就是外部存儲,但是在Android4.4以后的話,就目前而言,現(xiàn)在的手機自帶的存儲就很大,現(xiàn)在Android10.0的話,有的手機能達到256G的存儲,針對于這種情況,手機機身自帶的存儲也是外部存儲,如果再插入SD卡的話也叫外部存儲,因此對于外部存儲分為兩部分:SD卡和擴展卡內(nèi)存 我們通過一段代碼來獲取手機的外部存儲目錄,我們用的測試手機是三星G4,帶有插入SD卡的: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
File[] files = getExternalFilesDirs(Environment.MEDIA_MOUNTED);
for (File file : files) {
Log.e('file_dir', file.getAbsolutePath());
}
}對于以上代碼,打印的結(jié)果如下: 打印出兩行目錄,第一行目錄是機身自帶的外部存儲目錄,目錄結(jié)構(gòu)為:/storage/emulated/0/Android/data/packagename/files 第二行是存儲卡的目錄結(jié)構(gòu),路徑為:/storage/extSdCard/Android/data/packagename/files 擴展外部存儲 此目錄路徑需要通過context來獲取,同時在app卸載之后,這些文件也會被刪除。類似于內(nèi)部存儲。 getExternalCacheDir() 對應(yīng)外部存儲路徑:/storage/emulated/0/Android/data/packagename/cache getExternalFilesDir(String type) 對應(yīng)外部存儲路徑:/storage/emulated/0/Android/data/packagename/files SD卡存儲 SD卡里面的文件是可以被自由訪問,即文件的數(shù)據(jù)對其他應(yīng)用或者用戶來說都是可以訪問的,當(dāng)應(yīng)用被卸載之后,其卸載前創(chuàng)建的文件仍然保留。 對于SD卡上面的文件路徑需要通過Environment獲取,同時在獲取前需要判斷SD的狀態(tài):
getExternalStorageDirectory() 對應(yīng)外部存儲路徑:/storage/emulated/0 getExternalStoragePublicDirectory(String type) 獲取外部存儲的共享文件夾路徑如:
String externalStoragePublicDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();以上便是獲取相機DCIM目錄,對應(yīng)獲取的路徑為:/storage/emulated/0/DCIM。
getRootDirectory() 對應(yīng)獲取系統(tǒng)分區(qū)根路徑:/system getDataDirectory() 對應(yīng)獲取用戶數(shù)據(jù)目錄路徑:/data getDownloadCacheDirectory() 對應(yīng)獲取用戶緩存目錄路徑:/cache 相關(guān)概念區(qū)別
這兩個都位于內(nèi)部存儲目錄/data/data/packagename/下面,位于同一級別,前者是file目錄下面,后面是cache目錄下。
前者位于內(nèi)部存儲目錄/data/data/packagename/file下面,后者位于外部存儲目錄/storage/emulated/0/Android/data/packagename/files下面,它們都存在于應(yīng)用包名下面,也就是說屬于app應(yīng)用的,所以當(dāng)app卸載后,它們也會被刪除的。 對于前面提到的app下載升級功能,我們從服務(wù)器端下載的app需要放到外部存儲目錄下面,而不是內(nèi)部存儲目錄,因為內(nèi)部存儲目錄的空間很小。另外我也做了相關(guān)測試,如果將apk放到內(nèi)部存儲目錄file下面的話,安裝時會出現(xiàn)問題,提示解析包出錯。
在app中有清除數(shù)據(jù)和清除緩存這兩個概念,那么這兩者分別清除的是什么目錄下面的數(shù)據(jù)呢? 清除數(shù)據(jù) 清除數(shù)據(jù)清除的是保存在app中所有數(shù)據(jù),就是上面提到的位于packagename下面的所有文件,包含內(nèi)部存儲(/data/data/packagename/)和外部存儲(/storage/emulated/0/Android/data/packagename/)。當(dāng)然除了SD卡上面的數(shù)據(jù),SD卡上面的數(shù)據(jù)當(dāng)app卸載之后還會存在的。 清除緩存 緩存是程序運行時的臨時存儲空間,它可以存放從網(wǎng)絡(luò)下載的臨時圖片,從用戶的角度出發(fā)清除緩存對用戶并沒有太大的影響,但是清除緩存后用戶再次使用該APP時,由于本地緩存已經(jīng)被清理,所有的數(shù)據(jù)需要重新從網(wǎng)絡(luò)上獲取。為了在清除緩存的時候能夠正常清除與應(yīng)用相關(guān)的緩存,請將緩存文件存放在getCacheDir()或者 getExternalCacheDir()路徑下。 以上便是Android系統(tǒng)中管存儲目錄的一些知識。 |
|
|