星期四, 10月 06, 2011

Data Storage

Android應用程式學習筆記

Data Storage

Android為你儲存應用程式數據提供許多選擇,你依照你的需求選擇,比如,資料是否為應用程式私有或是其他應用程式也可存取的,以及需要多少空間儲存數據。

以下是你的選擇:
Shared Preference-儲存私人原始的鍵值對。
Internal Storage-儲存數據在裝置的記憶體中。
External Storage-儲存公開數據在外部記憶體中。
SQLite Database-儲存有結構的數據在私人資料庫中。
Network Connection-通過網路儲存數據在私人網路伺服器。

Android為你提供一個方法來公開自己的數據給其他應用程式-Content Provider,content provider是一個可選的組件,公開讀/寫你的應用程式數據,受你需求加以限制。


Using Shared Preference


SharedPreferences類提供普通架構,允許你儲存及取得原始資料型態的鍵值對,你可以使用SharedPreferences儲存任何原始數據:booleans、ints、floats、longs和strings。


有兩種方式可以取得SharedPreference物件:

  • getSharedPreference()-如果你需要多個preference檔案,由名稱區分,第一個參數設定preference檔案的名稱。
  • getPreference()-如果你只需要一個preference檔案為activity使用,因為你將只有一個preference檔案,所你不需要設定名字。
寫值:
1.呼叫edit()方法取得SharedPreferences.edit物件。
2.新增數值,比如putBoolean()或是putString()方法。
3.commit()方法提交新的數值。

讀值,使用SharedPreferences方法讀取數值,比如getBoolean()或是getString()。


public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";

    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .

       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }

    @Override
    protected void onStop(){
       super.onStop();

      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);

      // Commit the edits!
      editor.commit();
    }
}


Using the Internal Storage

你可以直接將檔案儲存在裝置的內部記憶體中,儲存在裝置內部記憶體的檔案是應用程式私有的,其他應用程式是無法存取它們。當用戶移除了應用程式後,它們也會跟著被移除。

建立並寫私有檔案到內部記憶體:
1.傳入檔案名稱與操作方式到openFileOutput()方法,它回傳FileOutputStream。
2.write()寫檔案。
3.close()關閉寫檔輸出流。

For example


String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
MODE_PRIVATE建立檔案並使它為你的應用程式私有的,其他模式有:MODE_APPEND、MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE。

從內部記憶體讀取數據:
1.傳入檔案名稱和讀取模式到openFileInput()方法,它回傳FileInputStream。
2.read()方法一個byte一個byte讀取數據。
3.close()關閉檔案輸入流。


Saving cache file

如果你想緩存一些數據,而不是要永久儲存,你應該呼叫getCacheDir()方法打開File,顯示你應該緩存檔案的內部目錄。

當裝置的記憶空間太低,Android會刪除緩存檔案來恢復記憶空間,然而,你不應該依賴系統來清理這些緩存檔案,你應該自己維持這些緩存檔案並有責任限制消耗的空間,當用戶移除應用程式,這些檔案也需要移除。

Other useful methods
getFileDir()-取得你的內部檔案可以儲存的地方的絕對路徑。
getDir()-建立內部儲存空間的目錄。
deleteDile()-刪除在儲存空間的檔案。
fileList()-回傳應用程式所存的檔案陣列。


Using the External Storage

每個兼容Android的裝置都支持分享的"外部儲存",你可以用來儲存數據。"外部儲存"可以是可移除的儲存設備(比如SD卡),或是不可移除的內部儲存空間。儲存在外部儲存空間的檔案是任何應用程式都可以讀取的且用戶可以修改它。


checking media availabilty

在使用外部儲存空間之前,你應該呼叫getExternalStorageState()方法,檢查與外部儲存空間的介面是否可用。介面可能安裝在電腦上、遺失、唯獨或一些其他狀態,以下有一個例子,示範如何檢查介面是否可用。


boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
    // We can read and write the media
    mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
    // We can only read the media
    mExternalStorageAvailable = true;
    mExternalStorageWriteable = false;
} else {
    // Something else is wrong. It may be one of many other states, but all we need
    //  to know is we can neither read nor write
    mExternalStorageAvailable = mExternalStorageWriteable = false;
}
此例子檢查外部儲存空間是否能讀寫,getExternalStorageState()方法回傳其他狀態,你可能需要檢查,比如,介面是否與電腦正在連結、完全遺失、已經被惡意移除等。當你的應用程式需要存取,你可以使用這些狀態告知用戶更多的資訊。

Accessing files on external storage

如果你使用API level 8或更高,使用openExternalFilesDir()打開File,顯示你要儲存檔案的外部儲存空間的目錄,該方法需傳入一個type參數,指定子目錄的型態,比如,DIRECTORY_MUSIC及DIRECTORY_RINGTONE(傳入null取得應用程式檔案的根目錄),該方法建立合適的目錄,藉著指定目錄的型態,你可以確認Android系統的介面掃描器正確地分類在系統的檔案(比如,鈴聲就會被辨識為鈴聲,而不是音樂),如果用戶刪除應用程式,該目錄與所有的內容都會被刪除。

如果使用API level 7或是更低,使用getExternalStorageDirectory()開啟檔案,顯示外部儲存空間的目錄,你應該在以下的目錄寫入數據:
/Andoird/data/<package_name>/files/
package_name是java-type的package名稱,比如,"com.example.android.app" 。如果用戶是用API level   8或是更高且他們刪除應用程式,該目錄及所有內容都會被移除。

Saving files that should be shared

如果你想儲存檔案,檔案不只是給你的應用程式使用,當應用程式被刪除時,它們是不會被刪除,把它們存在外部儲存空間的公開目錄。這些目錄放置在外部空間的根目錄,例如,Ringtone/、Music/、Picture/等。


  • Music/ - Media scanner classifies all media found here as user music.
  • Podcasts/ - Media scanner classifies all media found here as a podcast.
  • Ringtones/ - Media scanner classifies all media found here as a ringtone.
  • Alarms/ - Media scanner classifies all media found here as an alarm sound.
  • Notifications/ - Media scanner classifies all media found here as a notification sound.
  • Pictures/ - All photos (excluding those taken with the camera).
  • Movies/ - All movies (excluding those taken with the camcorder).
  • Download/ - Miscellaneous downloads.

Saving cache files



Using Databases

Android完整支持SQLite資料庫,你建立的任何資料庫都可以藉著名稱存取在應用程式的任何類,但應用程式以外的不行。

建立新的SQLite資料庫的方法建議是建立SQLiteOpenHelper物件並附寫onCreate()方法,在方法中你可以使用SQLite的命令建立新的資料表。


public class DictionaryOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 2;
    private static final String DICTIONARY_TABLE_NAME = "dictionary";
    private static final String DICTIONARY_TABLE_CREATE =
                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
                KEY_WORD + " TEXT, " +
                KEY_DEFINITION + " TEXT);";

    DictionaryOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DICTIONARY_TABLE_CREATE);
    }
}
你可以使用自己定義的建構式來實現SQLiteOpenHelper,從資料庫讀或寫,分別呼叫getWriteableDatabase()及getReadableDatabase(),這兩方法都會回傳一個SQLiteDatabase物件。

SQLiteDatabase.query()執行SQLite的查詢,它接收各種查詢參數,比如資料表查詢、projection、selection、columns、grouping及其他。為了更複雜的查詢,你應該使用SQLiteQueryBuilder,它提供建立複雜查詢命令的功能。

每個SQLite查詢都會回傳Cursor物件,它點出查詢的位置,它總是從資料庫查詢並讀取行與列來導航查詢結果。


Using a Network Connection

在之後的文章中介紹。

沒有留言:

張貼留言