Android中數據的存儲和訪問

數據存儲的位置有兩個:手機自帶的存儲空間(電腦的自帶硬盤)和外存儲設備(sdcard,移動硬盤,也有可能是固定在手機內部,用usb鏈接電腦後可以看到的存儲設備)

當使用context的openFileOutput()來保存文件時,文件會被保存在手機自帶的存儲空間中,而且根據保存時操作模式的不同而權限不同。手機自帶的存儲空間通常較小,適合存放一些小的文件。大的文件通常存放在SDCard中,保存在SDCard中的文件是其他應用都能訪問的。

SDCard使用方法:

第一步:添加SDCard使用權限

第二步:判斷SDCard是否可用Environment.getExternalStorageState();

                   需要判斷兩個狀態 是否安裝了SDCard(MEDIA_MOUNTED);是否有寫保護(MEDIA_MOUNTED_READONLY)

第三步:保存文件

File file = new File(“/mnt/sdcard”,filename);

FileOutputStream outStream = newFileOutputStream(file);

outStream.write(content.getBytes());

outStream.close();

在SDCard中創建文件時,文件目錄通過Environment.getExternalStorageDirectory()獲得可以屏蔽掉一些版本的差異。

 

數據存儲的方式有五種:

1.      文件

實際上是用javaSE中的IO技術

1)  通過上下文對象context快速得到文件輸出流對象

FileOutputStreamoutStream=context.openFileOutput(filename,mode);

outStream.write(str.getBytes());

Filename:輸出流所寫文件的文件名

Mode:權限控制及寫入方式(追加,覆蓋…)

eg:context.MODE_PRIVATE,私有操作模式:創建出來的文件只能被本應用使用,其他應用無法訪問該文件,並且以覆蓋方式寫入

          因爲是字節輸出流,所以要將寫入內容轉換成字節

         通過這種方式,文件會被保存在data/data/packagename/files文件夾下面

2)  通過上下文對象context快速得到文件輸出流對象

FileInputStream inStream=context.openFileInput(filename);

ByteArrayOutputStream outStream=new ByteArrayOutputStream();//字節數組輸出流對象,用來緩存字節數組在內存中

Byte []buffer=new byte[1024];

While((len=inStream.read(buffer))!=-1)//讀到文件結尾時read方法返回-1

{

            outStream.write(buffer,0, len);

}

Byte [] data = outStream.toByteArray();

3)  創建文件時所使用的操作模式

Context.MODE_PRIVATE:默認操作模式,如上述。

Context.MODE_APPEND:追加操作模式,檢查文件是否存在,存在就往文件末尾追加內容;若不存在,就創建文件,創建的文件只能被本應用訪問。

Context.MODE_WORLD_READABLE:表示當前文件可以被其他應用寫入

Context.MODE_WORLD_WRITABLE:表示當前文件可以被其他應用寫入

Android有一套自己的安全模型,當應用程序在安裝時系統會分配給它一個userid,當該應用要去訪問其他資源比如文件時,就需要userid匹配。默認情況下,任何應用創建的文件,SharedPreferences,數據庫都應該是私有的(位於/data/data/<packagename>/files/)其他應用無法訪問。除非在創建時就指定了context.MODE_WORLD_WRITABLE或者context.MODE_WORLD_READABLE

2.      SharedPreferences(偏好參數保存)

很多時候我們開發的軟件需要向用戶提供軟件參數設置的功能。對於軟件配置參數的保存,如果是window軟件通常我們會採用ini文件進行保存,如果是j2se應用,我們會採用properties屬性文件或者xml進行保存。如果是android應用,我們用什麼方式保存軟件配置參數呢?Android平臺給我們提供了一個SharedPreferences類,它是一個輕量級的存儲類,特別適合用於保存軟件配置參數。使用sharedpreferences保存數據,其背後是用xml文件存放數據,相當於是該類封裝了對xml文件進行操作的一些方法,保存的xml文件存放在/data/data/<packagename>/shared_prefs目錄下。

使用步驟:

1)  保存:

第一步:獲得sharedPreferences類的對象。

     SharedPreferencessharedPreferences=context.getSharedPreferences(filename,mode);

     Filename是SharedPreferences內部所使用的xml文件的名稱,不要自己加上後綴名.xml,mode是操作模式

第二步:獲取編輯器,並利用編輯器保存內容

     Editoreditor=sharedPreferences.edit();

     Editor.putString(key,value);

     Editor.putInt(key,value);

 第三步:提交修改,第二步實際並未寫入xml文件

     Editor.commit();

2)  讀取

Map<string ,string> params = new HashMap<String, String>();

第一步:獲得sharedPreferences對象

SharedPreferences preferences = context.getSharedPreferences(“itcast”,Context.MODE_PRIVATE);

 第二步:從對象中讀取參數

Params.put(“name”, preferences.getString(key , defualtvalue));

Params.put(“age”,String.valueOf(preferences.getInt(“age”,0)));

key是鍵值,通過key來查找得到值,defualtvalue是當該鍵值不存在時,返回一個默認的值。

3.      SQLite數據庫

Android對SQLite數據庫提供了全面的支持。在一個應用中創建的數據庫,可以被該應用中的任何類按照數據庫的名字來訪問,但是不允許別的應用訪問。

1)  創建數據庫:推薦的方法是繼承SQLiteOpenHelper類,然後重載它的onCreate方法,在這個方法中可以通過執行SQLite的命令來創建表。

SQLiteOpenHelper的方法:


構造函數: name爲數據庫的名稱,若該數據庫不存在則創建該數據庫,version是數據庫的版本號,注:通過構造方法獲得該類的實例時,並不會創建或者打開數據庫,而是在通過該對象調用getWritableDatabase()和getReadableDatabase()時纔會創建或者打開數據庫。

onCreate()方法:數據庫創建時調用,一般在此方法中建表。若是數據庫存在,則不會再調用該方法。

onUpgrade()方法:當數據庫存在,且新建該類實例對象時所傳入的版本號比之前的版本號大時,會調用此方法。一般在此方法中更新表的結構。如果想要在獲得數據庫時,調用此方法,則應該將版本號增加。

1)  數據庫的業務處理,增刪改查。有兩種方法:

傳統的sql語句

添加、刪除、修改所用到的函數是一樣的


先通過helper獲得可寫入的數據庫,準備好sql語句和相應參數,通過調用execSQL(String sql,Object[] params)來執行。其中sql語句中可能含有?佔位符,會用字符串數組params來賦值。

查詢操作:

分爲單條查詢和多條查詢:

首先獲得可讀取的數據庫,準備好sql語句和參數,調用rawQuery()來執行,返回一個Cursor對象,指向第一條返回記錄之前。通過cursor可以獲得返回記錄的列數,然後循環記錄每列的列名和值,注:列數是從0開始。可以用map<string,string>對象來存儲行記錄。在多條查詢時,用list<map<String,String>>來保存返回結果。

Android封裝好的方法

一般來說,上述方法無法返回SQL執行所影響的行數,使用Android封裝的方法更爲簡便。

在數據庫中插入記錄:


注意其中的第二個參數StringnullColumnHack.這個參數是可選的,或爲空,或者指定某一列的列名。如果爲空,則不允許插入空記錄,即values裏沒有存放任何東西。如果指定某一列,那麼如果遇到空記錄,系統會將該列的值賦值爲null,然後插入。ContentValues類型相當於一個Map,存放了所需要更新的列名,和更新值。

在數據庫中刪除記錄:


在數據庫中更改記錄:


在數據庫中查詢數據:


4.      內容提供者(Content Provider)

內容提供者管理了對一組結構化數據訪問,即提供了一組接口(方法)來響應數據訪問端的請求。內容提供者封裝了數據,提供了一種應用間共享數據的機制。如果需要將本應用的數據對外進行共享,你需要創建一個ContentProvider,而其他的應用訪問這些共享的數據時,通過ContentResolver來進行訪問。

URI:android系統中一般有很多個ContentProvider,如何訪問指定的ContentProvider呢?需要uri來唯一標識一個ContentProvider。在Provider端(相當於服務器),有一個待匹配的uri(通常會在這裏使用通配符,#代表任意長度的數字,*代表任意長度的字符串),在Resolver端,如果要訪問某個Provider,要給出訪問的uri。

URI格式:content://authority/path

                    Content://authority/path/id

第一條表示操作的數據是多條數據(通常是一個表),第二條表示操作的是某一條記錄。

Authority是在配置文件中申明ContentProvider時所指定的唯一的標識符。

而在Provider端,uri所表示的意義:

Com.example.sqlitetest/* :表示的是該Provider裏的所有表

Com.example.sqlitetest/student:表示該Provider只允許操作student表裏的內容

Com.example.sqlitetest/student/#::表示該provider只允許操作student表裏的某一條記錄

ContentProvider使用方法:

1.      因爲ContentProvider是android四大組件之一,所以需要在配置文件中進行聲明。


2.      編寫Provider類實現ContentProvider父類,並覆蓋其中的抽象方法。

需要定義的常量,其中的URIMatcher是用來進行uri匹配的輔助類,在靜態代碼塊中爲其初始化,添加了兩條待匹配的uri。第三個參數是匹配成功時返回的編碼,STUDENT表示對單條記錄進行操作,STUDENTS表示對多條記錄進行操作。

得到數據庫->匹配uri->根據匹配得到的編碼,執行相應的處理(單條記錄需要用到ContentUris取出id部分)

在客戶端訪問ContentProvider時的代碼:


先獲得Resolver然後準備參數,最後執行

5.      網絡

 



發佈了23 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章