ContentProvider學習筆記
上一章節我們編寫了自定義的一個StudentProvider,他提供了兩種供外界訪問數據的方式,content://come.demo.sqlite.studentprovider/t_student和content://come.demo.sqlite.studentprovider/t_student/#,這一章我們將講解其他應用程序將如何來訪問StudentProvider中的數據。
1、ContentResolver類介紹
我們知道StudentProvider繼承了ContentProvider類,並實現了insert(),update(),delete(),query(),getType()等方法,同樣的ContentResolver這個類也提供了insert(),update(),delete(),query()方法,當外部應用需要對ContentProvider中的數據進行添加、刪除、修改和查詢操作時,可以使用ContentResolver 類來完成,要獲取ContentResolver 對象,可以使用Activity提供的getContentResolver()方法
ContentResolver 類提供了與ContentProvider類相同簽名的四個方法:
public Uri insert(Uri uri, ContentValues values):該方法用於往ContentProvider添加數據。
public int delete(Uri uri, String selection, String[] selectionArgs):該方法用於從ContentProvider刪除數據。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):該方法用於更新ContentProvider中的數據。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):該方法用於從ContentProvider中獲取數據。
2、實例:對數據庫表t_student的增刪改查操作
(1)佈局文件main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btnAdd1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="插入數據1" /> <Button android:id="@+id/btnAdd2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="插入數據2" /> <Button android:id="@+id/btnSearch1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="查詢數據1" /> <Button android:id="@+id/btnSearch2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="查詢數據2" /> <Button android:id="@+id/btnUpdate1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="修改數據1" /> <Button android:id="@+id/btnUpdate2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="修改數據2" /> <Button android:id="@+id/btnDelete1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="刪除數據1" /> <Button android:id="@+id/btnDelete2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="刪除數據2" /> </LinearLayout>
(2)MainActivity來實現具體的操作
package com.demo.contentprovider; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; /** * 使用ContentResolver實現對數據庫表t_student的操作 * @author yinbenyang */ public class MainActivity extends Activity { private Button btnAdd1, btnAdd2, btnSearch1, btnSearch2, btnUpdate1, btnUpdate2, btnDelete1, btnDelete2; //匹配content://come.demo.sqlite.studentprovider/t_student路徑 private static final int ONE = 1; //匹配content://come.demo.sqlite.studentprovider/t_student/ private static final int TWO = 2; //日誌輸出 private static final String TAG = "ContentProvider"; //定義的一個Uri,這個是StudentProvider提供的一個內容提供者 private static String CONTENT_URI = "content://come.demo.sqlite.studentprovider/t_student"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnAdd1 = (Button) findViewById(R.id.btnAdd1); btnAdd2 = (Button) findViewById(R.id.btnAdd2); btnUpdate1 = (Button) findViewById(R.id.btnUpdate1); btnUpdate2 = (Button) findViewById(R.id.btnUpdate2); btnSearch1 = (Button) findViewById(R.id.btnSearch1); btnSearch2 = (Button) findViewById(R.id.btnSearch2); btnDelete1 = (Button) findViewById(R.id.btnDelete1); btnDelete2 = (Button) findViewById(R.id.btnDelete2); btnAdd1.setOnClickListener(listener); btnAdd2.setOnClickListener(listener); btnUpdate1.setOnClickListener(listener); btnUpdate2.setOnClickListener(listener); btnSearch1.setOnClickListener(listener); btnSearch2.setOnClickListener(listener); btnDelete1.setOnClickListener(listener); btnDelete2.setOnClickListener(listener); } private OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnAdd1: add(ONE); break; case R.id.btnAdd2: add(TWO); break; case R.id.btnUpdate1: update(ONE); break; case R.id.btnUpdate2: update(TWO); break; case R.id.btnDelete1: delete(ONE); break; case R.id.btnDelete2: delete(TWO); break; case R.id.btnSearch1: search(ONE); break; case R.id.btnSearch2: search(TWO); break; default: break; } } }; // 查詢數據 private void search(int type) { ContentResolver resolver = getContentResolver(); Uri url = null; // 指定查詢的列名 String projection[] = new String[] { "sid", "sname", "age" }; // 查詢的條件 String selection = ""; // 查詢條件的參數值 String[] selectionArgs = null; // 指定是否排序以及使用排序是時的排序規則 String sortOrder = ""; // 查詢結果爲一個Cursor Cursor cursor = null; switch (type) { case ONE: // parse方法通過傳入一個字符串來構造一個Uri對象 url = Uri.parse(CONTENT_URI); selection = "sid < ?"; selectionArgs = new String[] { "3" }; cursor = resolver.query(url, projection, selection, selectionArgs, sortOrder); while (cursor.moveToNext()) { Log.i(TAG, "sid=" + cursor.getInt(0) + ",sname=" + cursor.getString(1) + ",age=" + cursor.getShort(2)); Toast.makeText( this, "sid=" + cursor.getInt(0) + ",sname=" + cursor.getString(1) + ",age=" + cursor.getShort(2), Toast.LENGTH_SHORT) .show(); } break; case TWO: // 此時指定查詢id爲1的學生信息 url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1); selection = null; cursor = resolver.query(url, projection, selection, selectionArgs, sortOrder); while (cursor.moveToNext()) { Log.i(TAG, "sid=" + cursor.getInt(0) + ",sname=" + cursor.getString(1) + ",age=" + cursor.getShort(2)); Toast.makeText( this, "sid=" + cursor.getInt(0) + ",sname=" + cursor.getString(1) + ",age=" + cursor.getShort(2), Toast.LENGTH_SHORT) .show(); } break; default: break; } } // 刪除數據 private void delete(int type) { ContentResolver resolver = getContentResolver(); Uri url = null; String where = ""; String[] selectionArgs = null; switch (type) { case ONE: url = Uri.parse(CONTENT_URI); // 指定刪除id爲1,2的學生信息 where = "sid in(?,?)"; selectionArgs = new String[] { "1", "2" }; resolver.delete(url, where, selectionArgs); break; case TWO: // 指定刪除id爲3的學生信息 url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),3); Log.i(TAG, "url:" + url); where = null; resolver.delete(url, where, selectionArgs); break; default: break; } } // 修改數據 private void update(int type) { ContentResolver resolver = getContentResolver(); ContentValues values = new ContentValues(); Uri url = null; String where = ""; String[] selectionArgs = null; switch (type) { case ONE: url = Uri.parse(CONTENT_URI); values.put("sname", "update1"); values.put("age", 22); where = "sid = ?"; // 指定更新語句的條件(此時若不指定則是更新全部的數據) selectionArgs = new String[] { "1" }; // 指定佔位符的數值 Log.i(TAG, resolver.update(url, values, where, selectionArgs) + ""); break; case TWO: // 此時的Uri中包含了需要更新數據的id,所以不再需要指定更新語句的條件和參數值 url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),2); values.put("sname", "update2"); values.put("age", 22); where = null; Log.i(TAG, resolver.update(url, values, where, selectionArgs) + ""); break; default: break; } } // 插入數據 private void add(int type) { ContentResolver resolver = getContentResolver(); ContentValues values = new ContentValues(); values.put("sname", "zhaobenshan"); values.put("age", 23); Uri url = null; switch (type) { case ONE: url = Uri.parse(CONTENT_URI); // insert()方法返回一個Uri對象,這個對象是新插入的數據的Uri Log.i(TAG, resolver.insert(url, values).toString()); break; case TWO: /** * 這個構造一個Uri爲:content://com.demo.contentprovider.studentprovider/ * t_student/1,然後插入,實際上新插入的一條數據的id並不會爲1, * 因爲已經存在爲1的數據了,所以這個和上面的寫法一樣,生成的數據的id爲2 */ url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1); // insert()方法返回一個Uri對象,這個對象是新插入的數據的Uri Log.i(TAG, resolver.insert(url, values).toString()); break; default: break; } } }
頁面顯示的佈局效果:
而後我們還是利用命令去com.demo.sqlite.activity/database/data.db中查看t_student表
(1) 點擊插入數據1或者插入數據2,查看數據:
(2)點擊查詢數據1,可以看到彈出了id爲1和2的兩條數據,點擊查詢數據2可以看到只彈出id爲1的數據
(3)點擊修改數據1將t_student表中sid爲1的name改爲update1,age改爲22,點擊修改數據2將sid爲2的name改爲update2,age改爲22.
(4)點擊刪除數據1將id爲1,2的學生信息刪除:如圖刪除後只剩下id爲3的學生信息
點擊刪除數據2將id爲3的學生信息刪除,如圖,最後t_student表中已經沒有學生信息了
後記:t_student表是SqliteDemo應用程序中的表數據,而現在通過ContentProviderDemo程序也可以實現對t_student表的操作,由此可見,我們的ContentProvider實現數據在應用程序間的共享了