2010年11月1日 星期一

Android 資料儲存

一.資料儲存方式
在Android內要保存資料,有以下幾種方式可以選擇
1.SharedPreferences
    以key-value方式儲存只有Private data
2.Internal Storage
    使用device內部的記憶體儲存Private data
3.External Storage
    使用如SD卡這樣的外部儲存媒介,儲存Public data
4.SQLite Databases
    以資料庫結構儲存private data
5.Network Connection
    儲存資料到網路主機上
對於Private Data,在Android利用 Content Providers Class來作存取

二.SharedPreferences
利用 SharedPreferences Class可以將基本型別的資料(boolean,string,float,int..)以key-value方式作存取,data會持續保留在user session,即使app被砍了,資料還是保留著

1.取得SharedPreferences的兩種方式
1.需要用到多個Preference的狀況
  getSharedPreferences(name):如果需要用到多個
  preference file儲存,利用name來取得
  例:
  SharedPreferences settings = Context.getSharedPreferences("myPre", 0);
2.只需要用到一個Preference
  Activity.getPreferences(int mode):如果你的Activity
  只會用到一個preference

2.寫入preference的流程
1.呼叫edit()取得SharedPreferences.Editor
    SharedPreferences settings = getSharedPreferences("myPre", 0);
    SharedPreferences.Editor editor = settings.edit();
2.利用以下method把值寫入putBoolean() and putString()
    editor.putString("myStr", "strValue");
3.使用commit()把改變的資料真正寫入
    editor.commit();

3.讀取Preference值
使用SharedPreferences的getBoolean()、getString()等method
String str = settings.getString("myStr","defaultStr");

4.範例
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();
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);
      editor.commit();
    }
}

三.Internal Storage
你可以把資料直接儲存在device的內存,預設儲存在內存的檔案是只有該App可讀取,其他App無法讀取,當App移除時,這資料會一併被移除

1.在內存產生一個private file,寫入資料流程
1.提供一個檔案名稱來呼叫openFileOutput(name)
  取得FileOutputStream物件(Context的method)
2.FileOutputStream物件使用write()寫入資料    
3.FileOutputStream物件使用close()關閉檔案


String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
範例裡的參數MODE_PRIVATE是指當有同名檔案會自動覆蓋

2.由內存讀取檔案資料
1.提供檔名呼叫openFileInput(name)來取得
  FileInputStream物件
2.FileInputStream物件使用read()讀取bytes資料
3.FileInputStream物件使用close()關閉

3.使用暫存
若只是暫存資料,而不是永久存檔可以利用getCacheDir()來取得一個File物件當作暫存檔,當系統內存不足時,這些cacheFile就會被刪除,使用暫存檔需要自己時時去清理

4.其他method
1.getFilesDir()
    取得內存在檔案系統的目錄絕對路徑
2.getDir()
    在內存空間建立目錄或開啟已存在目錄
3.deleteFile()
    刪除內存檔案
4.fileList()
    取得目前App在內存所儲存的檔案清單Array

四.External Storage
所有Android相容device均支援利用外部儲存裝置來儲存檔案(如SD卡),
使用者利用USB即可將資料傳輸到電腦內

1.檢查外存媒介是否存在
在使用外存之前都需先用getExternalStorageState()檢查外存媒介是否存在


String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
    //可以對media作讀寫
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
    //只可以對media作讀取
} else {
    //無法作讀寫
}

2.讀取外存檔案
1.API level8
  使用 Context.getExternalFilesDir(String type)取得一個目錄的
  File物件,這method的type參數,是指定子目錄的類型,
  如DIRECTORY_MUSIC,DIRECTORY_RINGTONES或傳入null取得
  App root目錄,再透過File取得檔案,如果檔案已經存在則會打開
  該檔案。利用這method可直接建立目錄,當App移除時,目錄會跟著
  移除    
    
  例
  File path=Context.getExternalFilesDir(null);
  File file=new File(path,"mypic.jpg")    
2.API Level 7以下版本    
  則用Environment.getExternalStorageDirectory()取得根目錄的
  File物件,也就是讀取的資料會是在
  /Android/data/package_name/files/目錄下
  package_name是如同com.example.android.app的名稱
    
  例
  File path=Environment.getExternalStorageDirectory()
  File file=new File(path,"mypic.jpg")


3.儲存檔案
若要儲存檔案,不指定給特定App用,且希望在App移除時檔案不被刪除,
請儲存到外存上的 Music/, Pictures/, Ringtones/等目錄

1.API Level 8
  使用Context.getExternalStoragePublicDirectory(String type)
  取得目錄的File物件。這method的type參數,設定值為
  DIRECTORY_MUSIC, DIRECTORY_PICTURES,DIRECTORY_RINGTONES,
  如果目錄不存在,會自動產生
    
  例
  File path=Context.getExternalFilesDir(null);
  File file=new File(path,"mypic.jpg")
2.API Level 7 以下版本
  使用Environment.getExternalStorageDirectory()取得根目錄的
  File物件。儲存的資料會是在以下的目錄
  
  Music/ - media scanner會掃描這裡找音樂檔
  Podcasts/ - media scanner會掃描這裡找podcast.
  Ringtones/ - media scanner會掃描這裡找音樂手機檔鈴聲.
  Alarms/ - media scanner會掃描這裡找alarm sound.
  Notifications/ - media scanner會掃描這裡找notification sound.
  Pictures/ - 所有照片包括相機拍的都在這裡.
  Movies/ - 所有影片包括相機拍的都在這裡.
  Download/ - 其他下載檔案.
  
  例
  File rootPath=Environment.getExternalStorageDirectory();
  File path=new File( rootPath.getParent() + "/Music" );
  File file=new File(path,"my.mp3")  


4.使用暫存
1.API Level 8
  使用getExternalCacheDir() 開啟cache File,當App被移除時,
  檔案也會被自動移除,但在App還在的狀態下,使用者要自己管
  理暫存避免空間不足
2.API Level 7以下版本
  使用getExternalStorageDirectory()開啟cache File,檔案會被
  放在/Android/data/package_name/cache/目錄下

五.使用資料庫

1.建立資料庫
Android完全支援SQLite,在App內所有Class都可以透過name來使用DB
要在Android內操作使用DB,可以建立SQLiteOpenHelper 的子類別
並在override onCreate()內,建立產生所要的資料庫資料表


public class MyDbOpenHelper 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);
    }
}

2.資料庫存取
透過實體化這Class透過呼叫 getWritableDatabase() and getReadableDatabase()取得
SQLiteDatabase物件來對資料庫作讀寫,
查詢動作使用SQLiteDatabase query(),
若是比較複雜的查詢可以用SQLiteQueryBuilder,它會提供一些method來建立查詢

3.查詢結果
每次SQLite 作查詢都會回傳一個Cursor,用來指到查詢結果,
透過Cursor來瀏覽db資料

六.使用網路連線
使用網路連線來將資料儲存於遠端的伺服器
利用以下package提供的物件功能
java.net.*
android.net.*

4 則留言:

hanter 提到...

nice . TKS!

hanter 提到...
網誌管理員已經移除這則留言。
Unknown 提到...

受教了~ 謝謝拉~

很清楚

Unknown 提到...

受教了
謝謝~