本文實例講述了Android數據持久化之ContentProvider機制。分享給大家供大家參考,具體如下:
一般而言,android操作系統的應用程序所建立的數據只允許自己使用,應用程序彼此間無法借助公用存儲器來共享數據,android系統提供了一個機制,即內容提供器(ContentProvider),來公開自己私有的數據到數據內容器,通過該機制,可以供其他應用程序來讀取自己內部的數據,當然也可以訪問其他應用程序的數據。通常,內容提供器背后都有SQLite數據庫的支持,用以存儲內容提供內部數據。
實現ContentProvider與實現SQLite的區別:
應用程序實現SQLite時,由應用程序直接與數據庫進行對接,所以要在應用程序中實現SQLite的接口:db.onCreate()、db.insert()、db.update()、db.delete()、db.query()和db.close();
實現內容提供器時,在應用程序與數據庫之間要實現一個ContentProvider程序,這個ContentProvider程序會直接與數據庫進行對接,此時應用程序需要實現和ContentProvider程序接口的方法。
下面該說說如何建立內容提供器了:
首先,實現內容提供器接口:
實現該接口的5個重要方法;
其次,定義數據Uri:
提供器應用程序需要定義一個“基底”Uri,以供其他應用程序訪問這一內容提供器,這一個Uri必須是唯一的,且必須是以“content://”開頭,content: 表示內容提供器程序所控制數據的位置;在AndroidManifest.xml配置文件中添加如下代碼以進行聲明:
<!-- 設置類名和授權 multiprocess屬性是數據的同步性(同一時間可能有多個程序訪問該內容提供器)--><provider android:name="ContentProviderClass" android:multiprocess="true" android:authorities="com.example.data_contentprovider.ContentProviderClass" ></provider>
在應用程序中添加如下代碼:
//acquire the Uri of ContentProvidergetIntent().setData(Uri.parse("content://com.example.data_contentprovider.ContentProviderClass"));Uri uri = getIntent().getData();定義一個Uri所在的位置,并設置一個變量來找到內容提供器程序的接口;
如下是一個完整的代碼,功能是實現內容提供器的建立以及通過該內容提供器程序來添加和檢索數據:
實現內容提供器接口的代碼:
package com.example.data_contentprovider;import com.example.data_contentprovider.DB.DBHelper;import android.net.Uri;import android.content.ContentProvider;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteQueryBuilder;public class ContentProviderClass extends ContentProvider { DBHelper dataBaseHelper; // 定義DataBaseHelper類變量dataBaseHelper // 實現ContentProvider的onCreate方法 @Override public boolean onCreate() { // TODO Auto-generated method stub dataBaseHelper = new DBHelper(getContext()); return true; } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub SQLiteDatabase db = dataBaseHelper.getWritableDatabase(); db.insert("test", null, values); return null; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub SQLiteDatabase db = dataBaseHelper.getReadableDatabase(); SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); queryBuilder.setTables("test"); Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, null); return cursor; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; }}配置AndroidManifest.xml文件:
<!-- 設置類名和授權 multiprocess屬性是數據的同步性(同一時間可能有多個程序訪問該內容提供器)--><provider android:name="ContentProviderClass" android:multiprocess="true" android:authorities="com.example.data_contentprovider.ContentProviderClass" ></provider>
建立一個SQLite數據庫系統來存儲和管理數據,同時利用SQLiteOpenHilper類協助建立數據庫和SQLiteDatabase類來管理數據庫:
package com.example.data_contentprovider.DB;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.provider.BaseColumns;public class DBHelper extends SQLiteOpenHelper { // 建立test.db數據庫 public DBHelper(Context context) { super(context, "test.db", null, 1); } // 建立test表 @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table test (" + BaseColumns._ID + "integer primary key," + "name text," + "description text" + ");"); } // 更新新版本 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS test"); onCreate(db); }}下面就是provider的應用程序了:
package com.example.data_contentprovider;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.widget.ListView;import android.widget.SimpleAdapter;public class ContentProviderActivity extends Activity { String [] from = {"column00","column01","column02"}; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); //acquire the Uri of ContentProvider getIntent().setData(Uri.parse("content://com.example.data_contentprovider.ContentProviderClass")); Uri uri = getIntent().getData(); //create some data to test ContentValues values = new ContentValues(); values.put("name", "marry"); values.put("description", "123456"); getContentResolver().insert(uri, values); //獲取ContentResolver對象(在應用程序B中,通過ContentResolver獲取程序A的ContentProvider中的數據。) values.put("name", "hello"); values.put("description", "654321"); getContentResolver().insert(uri, values); //search db all colum,cursor point to first colum of result Cursor cursor = managedQuery(uri, null, null, null, null); cursor.moveToFirst(); //set ArrayList,view more field table ArrayList<Map<String,Object>> data = new ArrayList<Map<String,Object>>(); Map<String, Object> item; //from db read data and save to ArrayList data container for (int i = 0; i < cursor.getCount(); i++) { item = new HashMap<String, Object>(); item.put("column00", cursor.getString(0)); item.put("column01", cursor.getString(1)); item.put("column02", cursor.getString(2)); data.add(item); cursor.moveToNext(); } cursor.close(); //ArrayList container data save to listView ListView listView = new ListView(this); SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.activity_content_provider, from, new int[]{R.id.text1,R.id.text2,R.id.text3}); listView.setAdapter(adapter); setContentView(listView); }}provider應用程序就可以通過該內容提供器檢索數據庫并向其添加數據了。
ContentProvider中重要的幾個類:
UriMatcher:
要了解UriMatcher,首先需要了解android中的Uri表示方法,眾所周知,Uri為通用資源標識符,它代表的是要操作的數據,Android中的每一種資源(比如文本,圖像,視頻等)都可以用Uri來表示。Android中的Uri由以下三部分組成:”content://”(即authory),數據的路徑,資源標識ID(可選),其中如果存在ID,則表示某一個具體的資源,如果不存在ID,則表示路徑下的整體。因此addUri()函數的3個參數也是對應上面的那3個。UriMatcher的匹配過程分為3步:初始化UriMatcher;注冊需要用的Uri;與已經注冊的Uri進行匹配。
ContentResolver :
當使用ContentProvider在不同的應用程序中共享數據時,其數據的暴露方式是采取類似數據庫中表的方法。而ContentResolver 是恰好是采用類似數據庫的方法來從ContentProvider中存取數據的,它是通過Uri來查詢ContentProvider中提供的數據,查詢時,還需知道目的數據庫的名稱,數據段的數據類型,或者說資源的ID。
SQLiteQueryBuilder:
是一個用來生產SQL查詢語句的輔助類,可以方便的去訪問SQLiteDatabase. 在構造SQL查詢語句時,它同樣也需要指定表名,指定列名,指定where條件等。
希望本文所述對大家Android程序設計有所幫助。
新聞熱點
疑難解答