Android Learning:數據存儲方案概括與總結

 

前言

  最近在學習《第一行android代碼》和《瘋狂android講義》,個人感觸是Android應用的本質其實就是數據的處理,包括數據的接收,存儲,處理以及顯示,我想針對這幾環分別寫一篇博客,記得個人學習心得,也但願跟各位新手同窗相互努力促進。今天這篇博客,我想介紹一下數據的存儲,由於數據的接收,存儲,處理以及顯示這幾環環環相扣,而數據的存儲直接關係到數據的處理和顯示,因此顯得尤其重要。html

  因此本文針對數據存儲的常見方案和其使用進行了概括。分爲程序內存儲和程序間數據訪問,程序內存儲介紹了文件存儲、SharedPreferences存儲、數據庫存儲三種不一樣的存儲方式的優缺點以及區別,用用例子詳細說明了各自的用法,重點介紹了數據庫存儲的操做。 程序間數據訪問介紹了內容提供器。java

 

Android程序內數據存儲方案:

  Android系統中主要提供了三種方式用於簡單地實現數據持久化功能,即文件存儲、SharedPreferences存儲以及數據庫存儲。固然,除了這三種方式以外,還能夠將數據保存在手機的SD卡中,不過使用文件存儲、SharedPreferences存儲以及數據庫存儲會相對於將數據保存在手機的SD卡中更安全也更簡單一些[1]。 android

  1、文件存儲: 

  文件存儲是Android中最基本的一種數據存儲方式,它不對存儲的內容進行任何的格式化處理,全部數據都是原封不動地保存到文件當中的,於是它比較適合用於存儲一些簡單的文本數據或二進制數據。若是你想使用文件存儲的方式來保存一些較爲複雜的文本數據,就須要定義一套本身的格式規範,這樣方便於以後將數據從文件中從新解析出來。因爲文件存儲的方式有着起侷限性,在實際工程項目中用的不多,咱們也就不具體展開說。  sql

  2、SharedPreferences存儲: 

  不一樣於文件的存儲方式,SharedPreference是使用鍵值對的方式來存儲數據的。也就是說當保存一條數據的時候,須要給這條數據提供一個對應的鍵,這樣在讀取數據的時候就能夠經過這個鍵把相應的值取出來。並且SharedPreferences還支持多種不一樣的數據類型存儲,這就是SharedPreference比文件存儲的優越性所在。
shell

三種獲取SharedPreferences對象的方法數據庫

  • Context類中的getSharedPreferences()方法

        SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);

  第一個參數用於指定SharedPreferences文件的名稱。第二個參數指定操做模式,MODE_PRIVATE表示只有當前的應用程序才能夠對這個SharedPreferences進行讀寫,MODE_MULTI_PROCESS則通常用於會有多個進程中對同一個SharedPreferences文件進行讀寫的狀況。數組

  • Activity類中的getPreferences()方法

  跟Context類中的getSharedPreferences()方法很類似,不過只接受一個操做模式參數安全

  • PreferenceManager類中的getDefaultSharedPreferences()方法

        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);

  這是一個靜態方法,接收Context參數。app

例子:經過SharedPreferences進行讀寫數據ide

shareRead = (Button) findViewById(R.id.share_read);
shareWrite = (Button) findViewById(R.id.share_write);
/**
 * pref = PreferenceManager.getDefaultSharedPreferences(this);
 */
pref = getSharedPreferences("data", MODE_PRIVATE);
editor = pref.edit();
shareWrite.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        editor.putString("write", "This is A String");
        /*數據提交*/
        editor.commit();
    }
});
shareRead.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String str = pref.getString("write", null);
        Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
    }
});

  

  • 存儲數據(shareWrite)的實現

  1. 調用SharedPreferences對象的Edit()方法獲取一個SharedPreferences.Editor對象

  2. 向SharedPreferences.Editor對象中添加數據,採用putBoolean、putString等方法

  3. 調用commint()方法將添加的數據提交

  • 獲取數據(shareRead)的實現

  1. 直接採用SharedPreferences對象的get方法

  2. get方法接收兩個參數,第一個是鍵,第二個參數是默認值,當傳入的鍵找不大到對應的值,返回默認值

效果圖

   

  sharedPreferences對象與SQLite數據庫相比,免去了建立數據庫,建立表,寫SQL語句等諸多操做,相對而言更加方便,簡潔。可是SharedPreferences也有其自身缺陷,好比其只能存儲boolean,int,float,long和String五種簡單的數據類型,好比其沒法進行條件查詢等。因此不論SharedPreferences的數據存儲操做是如何簡單,它也只能是存儲方式的一種補充,而沒法徹底替代如SQLite數據庫這樣的其餘數據存儲方式[2]。 

  3、數據庫存儲

建立數據庫: SQLiteDatabase.execSQL()

public class MyDatabaseHelper extends SQLiteOpenHelper {
    /*創建一個student的數據表*/
    public static final String CREATE_STUDENT = "create table student ("
            + "id integer primary key autoincrement,"
            + "number integer,"
            + "name text,"
            + "major text)";

    private Context myContext;

    public MyDatabaseHelper(Context context, String name,
                            SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        myContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        /*建立數據庫*/
        db.execSQL(CREATE_STUDENT);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

更新數據庫:onUpgrade()

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      /*drop table if exists student:發現數據庫已經存在student這張表就刪除*/ 
      db.execSQL("drop table if exists student");
      onCreate(db);
}

當表中沒有咱們所要的數據時:

添加數據:insert(String table, String nullColumnHack, ContentValues values)

MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "student.db, null, 2");
SQLiteDatabase db = dbHelper. getWritableDatabase();
ContentValues values = new ContentValues();
values.put("number", 123456);
values.put("name", "steve");
values.put("major", "CS");
db.insert("student", null, values);

當表中數據已經存在,可是數據須要修改:

更新數據:update(String table, ContentValues values, String whereClause, String[] whereArgs)

db.update("student", values,  "name = ?", new String[]{"steve"});

     刪除數據:delete(String table, String whereClause, String[] whereArgs)

db.delete("student", "name = ?", new String[]{"steve"});

查詢數據:

Cursor query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy)    

     Cursor rawQuery(String sql, String[] selectionArgs) 

查詢表

query()方法參數 對應SQL部分 描述
table from table_name 指定查詢的代表
columns select column1,column2 指定查詢的列名
selection where column = value 指定where的約束條件
selectionArgs - 爲where中的佔位符提供具體的值
groupBy group by column 指定須要group by的列
having having column = value 對group by後的結果進一步約束
orderBy order by column1, column2 指定查詢結果的排序方式
Cursor cursor = db.query("student", null, "number = ?", new String[] {"123456"}, null, null, null);

  

  到這裏,咱們能夠看到update()、delete()、query()等方法中都傳入了String[] whereArgs參數,這是一個字符串數組,也是判斷條件,這能夠幫助咱們在同一個類目中搜索幾類關鍵字的數據

  • 使用事務:事務的特性能夠保證讓某一系列的操做要麼所有完成,要麼一個都不會完成

SQLiteDatabase中包含兩個方法控制事務:

開始事務:beginTransaction()

結束事務:endTransaction()

是否在事務中:inTransaction()

設置事務標誌:setTransactionSuccessful()

  表示事物執行成功。若是程序在事務執行中調用該方法設置了事務成功則提交事務,不然程序將會回滾事務。

  注意:

  數據庫查看,咱們能夠經過命令行方式進入SDK/platform-tools,輸入adb shell,便可輸入數據庫的基本指令。但我以爲這種方式並非很方便,個人作法是,登陸SQLite Expert官方網站(http://www.sqliteexpert.com/download.html)下載一個SQLite Expert Personal 3,我的版的是免費的。而後就能夠在Android Studio或者Eclipse中進如Android Monitor Device,在File Explorer中找到data/data/包名/database/*.db,點擊導出,而後就能夠用這個軟件打開。       


 

Android程序間數據內容提供器:

  上述三種方案是單個程序數據的存儲,而咱們在有些場景中,須要用到系統應用的數據,好比使用系統的通信錄、短信和媒體庫等功能,那這就須要咱們使用內容提供器(Content Provider),它能夠用於在不一樣的應用程序之間實現數據共享。

1、獲取其餘應用的數據

  內容提供器是經過ContentResolver類來訪問內容提供器中共享的數據,ContentResolver是由Context.getContentResolver() 獲得的。 

    Cursor cursor = getContentResolver().query(
        uri,
            projection,
            selection,
            selectionArgs,
            sortOrder) ;

查詢表

query()方法參數 對應SQL部分 描述
uri from table_name 指定查詢的代表
projection where column = value 指定where的約束條件
selection - 爲where中的佔位符提供具體的值
selectionArgs group by column 指定須要group by的列
orderBy order by column1, column2 指定查詢結果的排序方式

   講到這裏,咱們會發現,內容提供器的查詢方法跟數據庫很相似,使用query()方法,不一樣的是,傳進query()方法的參數有所區別。內容提供器傳進query的值包含着URI,而URI記錄着目標數據的地址,而數據庫傳進query的值包含着表名,由於數據庫是對自身程序文件目錄下進行的操做,因此並不須要定位,而內容提供器首先要定位到程序的包名,進而定位到數據文件夾,最終定位到表名,在URI中,咱們能夠看到最後一個斜槓後就是表名。

  • 內容URI 

URI的標準格式 

  content://com.example.app.provider/table 

URI的解析 

  Uri uri = Uri.parse("content://com.example.app.provider/table") 

URI規則 

    * 表示匹配任意長度的任意字符

    content://com.example.app.provider/*

    # 表示匹配任意長度的數字

    content://com.example.app.provider/table/#

2、提供應用自身的數據  

  • 內容提供器的六個方法

    一、onCreate()

      初始化內容提供器。完成數據庫的建立和升級,只有在ContentResolver嘗試訪問程序數據纔會被初始化

    二、query()

      查詢數據。uri肯定查哪張表,projection查詢列,selection和selectionArgs查詢哪些行

    三、insert()

      添加數據

    四、update()

      更新內容提供器已有的數據

    五、delete()

      刪除數據

    六、getType()

      根據傳入的內容URI來返回相應的MIME類型。

      一個內容URI對應的MIME字符串只要有三部分組成

        (1)必須以vnd開頭  

        (2)以路徑結尾,後接android.cursor.dir/,以id結尾,後接android.cursor.item/  

        (3)最後接上vnd.<authority>.<path>        

  • 匹配內容URI

    UriMatcher類

    addURI()方法,這個方法接受三個參數,分別把權限、路徑和一個自定義代碼傳進去

    match()方法,將Uri對象傳入,返回值是某個可以匹配這個Uri對象說對應的自定義代碼

  內容提供類的核心是經過URI對象來定位數據的,但數據定位成功以後,那麼就能夠用相似於數據庫操做的手段進行讀取。若是想共享自身的數據,也能夠經過URI對象,拋出本身的位置,等待其餘程序定位到自身獲取數據 

總結:   

存儲方式 用途 特色
文件存儲 存儲一些簡單的文本數據或二進制數據 不對存儲的內容進行任何的格式化處理
SharedPreferences存儲 存儲boolean,int,float,long和String五種簡單的數據類型,數據量小 方便,簡潔,使用鍵值對的方式來存儲數據,支持多種不一樣的數據類型存儲,但不能條件查詢
數據庫存儲 數據量大,且有條件 功能強大,條件查詢,數據的增刪改查,但使用較爲複雜
內容提供器 跨程序之間的數據交換 經過URI對象來定位數據源

 

 

[1] 郭霖. 第一行代碼 Android[J]. 2014.

[2] 大氣象.Android四種存儲方式.http://www.cnblogs.com/greatverve/archive/2011/12/27/android-sharedpreference-file-SQlite-contentprovider.html

相關文章
相關標籤/搜索