android保存 數(shù)據(jù)

主要 3類 : (不包含保存在 網(wǎng)絡(luò)服務(wù)器)

  • SharedPreferences 鍵值對
  • 數(shù)據(jù)庫
  • 文件

SharedPreferences

以下代碼在 Fragment

自定義key

Context context = getActivity();
SharedPreferences sharedPref = context.getSharedPreferences(
        getString(R.string.preference_file_key), Context.MODE_PRIVATE);

也可以使用默認key

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE)
寫入

用 edit() 來創(chuàng)建一個 SharedPreferences.Editor

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit(); //再此可以添加 
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();

讀取
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);

保存文件

所有 Android 設(shè)備都有兩個文件存儲區(qū)域:“內(nèi)部”和“外部”存儲。

內(nèi)部存儲:
  • 它始終可用。
  • 只有您的應(yīng)用可以訪問此處保存的文件。
  • 當用戶卸載您的應(yīng)用時,系統(tǒng)會從內(nèi)部存儲中移除您的應(yīng)用的所有文件。

當您希望確保用戶或其他應(yīng)用均無法訪問您的文件時,內(nèi)部存儲是最佳選擇。

外部存儲:
  • 它并非始終可用,因為用戶可采用 USB 存儲設(shè)備的形式裝載外部存儲,并在某些情況下會從設(shè)備中將其移除。

  • 它是全局可讀的,因此此處保存的文件可能不受您控制地被讀取。

  • 當用戶卸載我們的app時,系統(tǒng)僅僅會刪除external根目錄(getExternalFilesDir())下的相關(guān)文件

  • 對于無需訪問限制以及您希望與其他應(yīng)用共享或允許用戶使用計算機訪問的文件,外部存儲是最佳位置。

提示:盡管應(yīng)用默認安裝在內(nèi)部存儲中,但您可在您的清單文件中指定 android:installLocation
屬性,這樣您的應(yīng)用便可安裝在在外部存儲中。當 APK 非常大且它們的外部存儲空間大于內(nèi)部存儲時,用戶更青睞這個選擇。 如需了解詳細信息,請參閱應(yīng)用安裝位置。

獲取外部存儲的權(quán)限

您必須在您的清單文件中請求 WRITE_EXTERNAL_STORAGE 權(quán)限。

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest

讀取外部存儲(但不向其寫入信息),那么您將需要聲明 READ_EXTERNAL_STORAGE權(quán)限。要確保您的應(yīng)用繼續(xù)正常工作,您應(yīng)在更改生效前聲明此權(quán)限。

您無需任何權(quán)限,即可在內(nèi)部存儲中保存文件。 您的應(yīng)用始終具有在其內(nèi)部存儲目錄中進行讀寫的權(quán)限。

保存在 內(nèi)部文件

務(wù)必刪除所有不再需要的文件并對在指定時間您使用的內(nèi)存量實現(xiàn)合理大小限制,比如,1MB。 如果在系統(tǒng)即將耗盡存儲,它會在不進行警告的情況下刪除您的緩存文件。

要在這些目錄之一中新建文件,您可以使用 [File()](https://developer.android.google.cn/reference/java/io/File.html#File(java.io.File, java.lang.String)) 構(gòu)造函數(shù),傳遞指定您的內(nèi)部存儲目錄的上述方法之一所提供的 File
例如:

File file = new File(context.getFilesDir(), filename);

或者,您可以調(diào)用 [openFileOutput()](https://developer.android.google.cn/reference/android/content/Context.html#openFileOutput(java.lang.String, int))獲取寫入到內(nèi)部目錄中的文件的 FileOutputStream
例如
下面顯示如何向 ** 內(nèi)部文件 **寫入一些文本:

String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;

try {
//獲取內(nèi)部文件的流
  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
  outputStream.write(string.getBytes());
  outputStream.close();
} catch (Exception e) {
  e.printStackTrace();
}

或者,如果您需要緩存某些文件,您應(yīng)改用 [createTempFile()](https://developer.android.google.cn/reference/java/io/File.html#createTempFile(java.lang.String, java.lang.String))
例如,以下方法從 URL提取文件名并正在您的應(yīng)用的內(nèi)部緩存目錄中以該名稱創(chuàng)建文件:

public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
        file = File.createTempFile(fileName, null, context.getCacheDir());
    } catch (IOException e) {
        // Error while creating file
    }
    return file;
}

注:您的應(yīng)用的內(nèi)部存儲設(shè)備目錄由您的應(yīng)用在 Android 文件系統(tǒng)特定位置中的軟件包名稱指定。
Note: 我們的app的internal storage 目錄以app的包名作為標識存放在Android文件系統(tǒng)的特定目錄下[data/data/com.example.xx]。
技術(shù)上講,如果文件被設(shè)置為可讀的,那么其他app就可以讀取該internal文件。然而,其他app需要知道包名與文件名。若沒有設(shè)置為可讀或者可寫,其他app是沒有辦法讀寫的。因此我們只要使用了MODE_PRIVATE ,那么這些文件就不可能被其他app所訪問

將文件保存在外部存儲中

由于外部存儲可能不可用—比如,當用戶已將存儲裝載到電腦或已移除提供外部存儲的 SD 卡時—因此,在訪問它之前,您應(yīng)始終確認其容量。 您可以通過調(diào)用 getExternalStorageState()查詢外部存儲狀態(tài)。 如果返回的狀態(tài)為 MEDIA_MOUNTED
,那么您可以對您的文件進行讀寫。

/* Checks if external storage is available for read and write 
檢查容量 是否能夠進行寫
*/
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

盡管外部存儲可被用戶和其他應(yīng)用進行修改,但您可在此處保存兩類文件:

  • 公共文件
    應(yīng)供其他應(yīng)用和用戶自由使用的文件。 當用戶卸載您的應(yīng)用時,用戶應(yīng)仍可以使用這些文件。
    例如,您的應(yīng)用拍攝的照片或其他已下載的文件

  • 私有文件
    屬于您的應(yīng)用且在用戶卸載您的應(yīng)用時應(yīng)予刪除的文件。 盡管這些文件在技術(shù)上可被用戶和其他應(yīng)用訪問(因為它們存儲在外部存儲中), 但它們實際上不向您的應(yīng)用之外的用戶提供任何輸出值。 當用戶卸載您的應(yīng)用時,系統(tǒng)會刪除應(yīng)用外部私有目錄中的所有文件。
    例如,您的應(yīng)用下載的其他資源或臨時介質(zhì)文件。

公共文件保存在外部存儲設(shè)備上,請使用 getExternalStoragePublicDirectory()方法獲取表示外部存儲設(shè)備上相應(yīng)目錄的 File
該方法使用指定您想要保存以便它們可以與其他公共文件在邏輯上組織在一起的文件類型的參數(shù),比如 DIRECTORY_MUSICDIRECTORY_PICTURES。
例如:

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

文件以私有形式保存在external storage中,您可以通過調(diào)用 getExternalFilesDir()
并向其傳遞指示您想要的目錄類型的名稱,從而獲取相應(yīng)的目錄。通過這種方法創(chuàng)建的各個目錄將添加至封裝您的應(yīng)用的所有外部存儲文件的父目錄,當用戶卸載您的應(yīng)用時,系統(tǒng)會刪除這些文件。
例如,您可以使用以下方法來創(chuàng)建個人相冊的目錄:

public File getAlbumStorageDir(Context context, String albumName) {
    // Get the directory for the app's private pictures directory.
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

無論您對于共享的文件使用 getExternalStoragePublicDirectory()還是對您的應(yīng)用專用文件使用 getExternalFilesDir(),您使用諸如DIRECTORY_PICTURES的 API 常數(shù)提供的目錄名稱非常重要。這些目錄名稱可確保系統(tǒng)正確處理文件。

請記住,getExternalFilesDir() 方法會創(chuàng)建的目錄會在app被卸載時被系統(tǒng)刪除。如果我們的文件想在app被刪除時仍然保留,請使用getExternalStoragePublicDirectory().

例如,保存在 DIRECTORY_RINGTONES中的文件由系統(tǒng)媒體掃描程序歸類為鈴聲,而不是音樂。

查詢可用空間

如果您事先知道您將保存的數(shù)據(jù)量,您可以查出是否有足夠的可用空間,而無需調(diào)用 getFreeSpace()getTotalSpace()引起 IOException。這些方法分別提供目前的可用空間和存儲卷中的總空間。 此信息也可用來避免填充存儲卷以致超出特定閾值。

但是,系統(tǒng)并不保證您可以寫入與 getFreeSpace()指示的一樣多的字節(jié)。如果返回的數(shù)字比您要保存的數(shù)據(jù)大小大出幾 MB,或如果文件系統(tǒng)所占空間不到 90%,則可安全繼續(xù)操作。否則,您可能不應(yīng)寫入存儲。

注:保存您的文件之前,您無需檢查可用空間量。 您可以嘗試立刻寫入文件,然后在 IOException出現(xiàn)時將其捕獲。 如果您不知道所需的確切空間量,您可能需要這樣做。
例如,如果在保存文件之前通過將 PNG 圖像轉(zhuǎn)換成 JPEG 更改了文件的編碼,您事先將不知道文件的大小。

刪除文件

您應(yīng)始終刪除不再需要的文件。刪除文件最直接的方法是讓打開的文件參考自行調(diào)用 delete()
myFile.delete();

如果文件保存在內(nèi)部存儲中,您還可以請求 Context
通過調(diào)用 deleteFile()來定位和刪除文件:
myContext.deleteFile(fileName);

:當用戶卸載您的應(yīng)用時,Android 系統(tǒng)會刪除以下各項:

  • 您保存在外部存儲中的所有文件您使用 getExternalFilesDir()
  • 保存在內(nèi)部存儲中的所有文件。

但是,您應(yīng)手動刪除使用 getCacheDir() 定期創(chuàng)建的所有緩存文件并且定期刪除不再需要的其他文件。

數(shù)據(jù)庫 就不多介紹了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,680評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,300評論 25 708
  • Ubuntu的發(fā)音 Ubuntu,源于非洲祖魯人和科薩人的語言,發(fā)作 oo-boon-too 的音。了解發(fā)音是有意...
    螢火蟲de夢閱讀 100,805評論 9 468
  • 晚春雨 壓絨花 梧桐 綠柳 露新顏 少年行 嘆別離 柳成蔭時可歸? 可歸!
    Lovato閱讀 312評論 0 0
  • 在這個時代,想要判斷自己是否能緊跟潮流的標準之一,就是對那些新創(chuàng)造出來的節(jié)日或者名詞,有沒有足夠的敏感,或者...
    滑過指尖的時光閱讀 1,684評論 0 0

友情鏈接更多精彩內(nèi)容