前面四篇文章主要介紹了文件存儲要尔、SharedPreference存儲、數據庫存儲這三種方式來存儲數據司训,但這三種方式所保存的數據都只能在當前應用程序中訪問。
如何才能實現跨程序數據共享的功能呢纲菌?
Content Provider作為四大組件之一在這里就派上用場了钱慢。為什么要共享數據?
這個要視情況而定缘眶,比如說賬號和密碼這類隱私數據顯然是不能共享給其他程序的嘱根,而有一些數據是可以提供給其他程序進行二次開發(fā)的,比如系統(tǒng)的電話簿程序巷懈,它的數據庫中保存很多聯系人信息该抒,如果這些數據不允許第三方應用訪問的話,那么很多應用就要大打折扣了砸喻。
Content Provider簡介
Content Provider主要用于在不同的應用程序之間實現數據共享的功能柔逼,它提供了一套完整的機制蒋譬,允許一個程序訪問另一個程序中的數據,同時還能保證被訪問數據的安全性愉适。
Content Provider的用法有兩種犯助,一種是使用現有的Content Provider來讀取和操作相應程序中的數據,另一種是創(chuàng)建自己的Content Provider給我們程序的數據提供外部訪問的接口维咸。
訪問其他應用程序中的數據
當一個應用程序通過Content Provider對其數據提供了外部訪問接口剂买,任何其他的應用程序就都可以對這部分數據進行訪問。Android系統(tǒng)中自帶的電話簿癌蓖、短信瞬哼、媒體庫等程序都提供了類似的訪問接口。接下來就看看Content Provider到底是如何使用的租副。
ContentResolver
如果想要訪問Content Provider中共享的數據坐慰,就一定要借助ContentResolver類,可以通過Context中的getContentResolver()方法獲取到該類的實例用僧。ContentResolver中提供了一系列的方法用于對數據的CRUD操作结胀,其中與SQLiteDatabase相同的是insert()方法用于添加數據,update()方法用于更新數據责循,delete()方法用于刪除數據糟港,query()方法用于查詢數據。
不同于SQLiteDatabase院仿,ContentResolver的增刪改查方法接收不是表名秸抚,而是使用一個Uri參數代替,這個參數被稱為內容URI歹垫。內容URI給Content Provider中的數據建立了唯一標識符剥汤,它有兩部分組成,
權限(authority)和路徑(path)排惨。權限是對不同的應用程序進行區(qū)分的秀姐,一般都會采用包名的方式來進行命名。比如包名為com.example.app若贮,那么對應的權限就可以命名為com.example.app.provider省有。
路徑則是對同一應用程序中不同的表做區(qū)分的,通常都會添加到權限后面谴麦。比如某個程序的數據庫里存在兩張表蠢沿,table1和table2,這時就可以將路徑分別命名為/table1和/table2匾效,然后把權限和路徑進行組合舷蟀,內容URI就變成了com.example.app.provider/table1 和 com.example.app.provider/table2。這兩個字符串還難以看出就是內容URI,因此還需要在頭部加上協議聲明野宜,標準的內容URI的寫法如下:
content://com.example.app.provider/table1
content://com.example.app.provider/table2
ContentResolver的CRUD操作接收的是URI參數扫步,所以還需要將上面的字符串解析為URI,代碼如下匈子。
Uri uri = Uri.parse("content://com.example.app.provider/table1")
1. query()
現在就可以使用這個Uri對象來查詢table1表中的數據了河胎,代碼如下:
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
這些參數和SQLiteDatabase中的query()方法里的參數很像,但是要相對簡單一些虎敦。下表就對這部分參數進行詳細的解釋游岳。
query()方法參數 | 對應SQL部分 | 描述 |
---|---|---|
uri | from table_name | 指定查詢某個應用程序下的某一張表 |
projection | select column1,column2 | 指定查詢的列名 |
selection | where column = value | 指定where的約束條件 |
selectionArgs | 為where中的占位符提供具體的值 | |
orderBy | order by column1,column2 | 指定查詢結果的排序方式 |
查詢完成后返回的仍然是一個Cursor對象,這時我們就可以將數據從Cursor 對象中逐個讀取出來了其徙。讀取的思路仍然是通過移動游標的位置來遍歷Cursor的所有行胚迫,然后再取出每一行中相應列的數據,代碼如下所示:
if (cursor != null) {
while (cursor.moveToNext()) {
String column1 = cursor.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
}
cursor.close();
}
2. insert()
掌握了最難的查詢操作唾那,剩下的增加访锻、修改、刪除操作就更不在話下了闹获。我們先來看看如何向table1表中添加一條數據朗若,代碼如下所示:
ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);
可以看到,仍然是將待添加的數據組裝到ContentValues中昌罩,然后調用 ContentResolver的insert()方法,將Uri和ContentValues作為參數傳入即可灾馒。
3. update()
現在更新一下剛剛新添加的數據茎用,把column1的值清空,可以使用ContentResolver的update()方法實現睬罗,代碼如下:
ContentValues values = new Contentvalues();
values.put("column1","");
getContentResolver().update(uri,values,"column1 = ? and column2 = ?",new String[] {"text","1"});
上述代碼使用了selection和selectionArgs參數來對想要更新的數據進行約束轨功,以防止所有的行都會受影響,即把values的值更新到"column1 = text"并且"column2 = 1"的表中容达。
4. delete()
最后古涧,調用ContentResolver的delete()方法將這條數據刪除掉,代碼如下:
getContentResolver().delete(uri,"column2 = ?",new String[] {"1"});
至此花盐,ContentResolver的CURD方法全部學完了羡滑,下一篇文章Android ContentProvider(二)就利用ContentProvider讀取系統(tǒng)電話簿中的聯系人信息。
如果文章對你有所幫助算芯,那么請您點一下?
由于本人水平有限柒昏,如有錯誤,歡迎大家指正熙揍。如果你在操作過程中發(fā)現一些沒有講到的錯誤或者問題职祷,歡迎在評論留言,一起探討,共同學習進步有梆!