Android學習筆記十九.使用ContentProvider實現資料共用(一),androidprovider

來源:互聯網
上載者:User

Android學習筆記十九.使用ContentProvider實現資料共用(一),androidprovider
一、Android如何?資料共用?     為了在應用程式之間交換資料,Android提供了ContentProvider,ContentProvider是不同應用程式之間進行資料交換的標準API,當一個應用程式需要把自己的資料暴露給其他程式使用時,該應用程式就可通過提供ContentProvider來實現,其他的應用程式就可以通過ContentResolver來操作ContentProvider暴露的資料。一旦某個應用程式通過ContentProvider暴露了自己的資料操作介面,那麼不管該應用程式是否啟動,其他應用程式都可以通過該介面來操作該應用程式的內部資料,包括增加資料、刪除資料、修改資料、查詢資料等。總結:A應用通過ContentProvider暴露自己的資料,B應用通過ContentResolver來操作ContentProvider暴露的資料。        A應用以某種Uri的形式對外提供資料,B應用使用ContentResolver根據A應用提供的Uri獲得A應用的authority 屬性去訪問操作指定的資料。二、ContentProvider與ContentResolver簡介
1.功能:(1)ContentProvider是不同應用程式之間進行資料交換的標準API,ContentProvider以某種Uri的形式對外提供資料,運行其他應用訪問或修改資料,即其他應用程式使用ContentResolver根據Uri去訪問操作指定資料, UriMatcher類用於協助解析URI。在實際應用中,自訂的ContentProvider類除了需要繼承ContentProvider之外,還需要同時實現以下方法(均為抽象方法):    - abstract boolean onCreate()    - abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)     -abstract Uri insert(Uri uri, ContentValues values)    - abstract int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)    - abstract int delete(Uri uri, String selection, String[] selectionArgs)    - abstract String getType(Uri uri) (2)Contentprovider相當於一個"網站",它的作用是暴露可供提供操作的資料。其他應用程式則通過ContentResolver來操作ContentProvider所暴露的資料,即ContentResolver相當於HttpClient。    一般來說,ContentProvider是單一實例模式,當多個應用程式通過ContentResolver來操作ContentProvider提供的資料時,ContentResolver調用的資料操作將會委託給同一個ContentProvider處理。

升華筆記1:ContentResolver是如何?訪問、修改Uri對應的ContentProvider中的資料?    從ContentResolver、ContentProvider和Uri的關係來看,Uri是ContentResolver和ContentProvider進行資料交換的標識。    ContentResolver對指定Uri執行CRUD等資料操作,但Uri並不是真正的資料中心,因此這些CRUD操作會委託給該Uri對應的ContentProvider來實現。舉個例子:假如B應用通過ContentResolver執行CUUD操作,這些CRUD操作都需要指定Uri參數,Android系統就根據該Uri找到對應的ContentProvider(該ContentProvider屬於A應用),ContentProvider複雜實現CRUD方法,完成對底層資料的增、刪、改、查等操作,即實現了B應用訪問A應用資料的目的。注釋:這裡的CRUD操作,指的是當B應用調用ContentResolver的insert()方法是,實際上相當於調用了該Uri對應的ContentProvider(屬於A應用)的insert()方法。 2.API ContentProvider
(1)繼承關係public abstract classjava.lang.Object     ↳ android.content.ContentProvider(2)構造方法
ContentProvider()Construct a ContentProvider instance.
(3)常用方法 abstract boolean onCreate():該方法在ContentProvider建立後會被調用,當其他應用程式第一次訪問ContentProvider時,該 ContentProvider會被建立出來,並立即回調該onCreate()方法;abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):根據Uri查詢出select條件所匹配的全部記錄,其中projection就是一個列名列表,表明只選擇指定的資料列;abstract Uri insert(Uri uri, ContentValues values):根據該Uri插入values對應的資料abstract int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):根據Uri修改selection條件所匹配的全部記錄abstract int delete(Uri uri, String selection, String[] selectionArgs):根據Uri刪除select條件所匹配的全部記錄;abstract String getType(Uri uri) :該方法用於返回當前Uri所代表的資料的MIME類型。如果該Uri對應資料可能包括多條記錄,那麼MIME類型字串應用以vnd.android.cursor.dir/開頭。如果該Uri對應的資料只包含一條記錄,那麼返回MIME類型字串應該以vnd.android.cursor.item/開頭。
ContentResolver
(1)繼承關係public abstract classjava.lang.Object   ↳ android.content.ContentProvider(2)構造方法(建立ContentResolver對象)
ContentResolver(Context context)
此外,Content提供了getContentResolver()方法來擷取一個ContentResolver對象。也就是說,Activity、Service等組件都可通過getContentResolver()方法擷取ContentResolver對象,這樣我們再調用ContenResolver的如下方法就可以操作暴露的資料了。                                                                    ContentResolver contentResolver=getContentResolver(); (3)常用方法   final int delete(Uri url, String where, String[] selectionArgs):刪除Uri對應的ContentProvider中where提交匹配的資料;final String getType(Uri url):擷取給定Content URL的MIME類型;final Uri insert(Uri url, ContentValues values):向Uri對應的ContentProvider中插入values對應的資料;
Parameters:
url The URL of the table to insert into.
values The initial values for the newly inserted row. The key is the column name for the field. Passing an empty ContentValues will create an empty row.
Returns:
the URL of the newly created row.
final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):查詢Uri對應的ContentProvider中where提交匹配的資料;Parameters:
uri The URI, using the content:// scheme, for the content to retrieve.
projection A list of which columns to return. Passing null will return all columns, which is inefficient.
selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given URI.
selectionArgs You may include ?s in selection, which will be replaced by the values from selectionArgs, in the order that they appear in the selection. The values will be bound as Strings.
sortOrder How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
Returns:
A Cursor object, which is positioned before the first entry, or null
final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer):註冊一個觀察類,當暴露的URI對應的ContentProvider中的資料發生變化時調用該方法final int update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri對應的ContentProvider中where提交匹配的資料;
ContentValues    This class is used to store a set of values that the ContentResolver can process.(1)繼承關係java.lang.Object    ↳ android.content.ContentValues(2)建構函式
ContentValues()Creates an empty set of values using the default initial size
ContentValues(int size)Creates an empty set of values using the given initial size
ContentValues(ContentValues from)Creates a set of values copied from the given set
(3)常用方法void put(String key, Byte value) :添加鍵值對值到set集合Set<Entry<String, Object>> valueSet() :返回set集合中所有的鍵對象和值對象int size() :返回set集合中值的數量
Cursor介面(1)功能概述:該介面主要用於隨機讀寫從資料庫查詢返回的set集合形式的結果。Cursor的實現不需要同步,所有當我們使用Cursor介面時,多線程使用Cursor時只需要注意自身同步即可。(2)常用方法:abstract void close() :關閉Cursor,釋放所有資源abstract void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) :擷取需要的列文本並將其儲存到提供的buffer數組中abstract int getPosition() :返回set集合中cursor遊標當前的行位置abstract boolean isNull(int columnIndex) :當指定的列為null時返回為trueabstract boolean move(int offset) :把當前遊標位置向前或向後移動offset數量abstract boolean moveToNext() :將遊標移動到下一行
三、ContentProvider與ContentResolver開發思路 1.ContentProvider開發思路(A應用提供ContentResolver介面)(1)定義一個ContentProvider子類。該子類需要繼承Android提供的ContentProvider基類,並且需要實現query()、insert()、update()和delete()(抽象方法)等方法;(2)配置ContentProvider。在該ContentProvider供其他應用調用之前,需要向Android系統註冊ContentProvider,即在A應用的工程檔案AndroidManifest.xml檔案中註冊這ContentProvider(類似於註冊Activity),且註冊ContentProvider時需要為它綁定一個Uri;  <provider android:name=".FirsttProvider"                                                        //指定該ContentProvider的實作類別的類名                android:authorities="com.example.Android.ContentProvider_1"        //指定該ContentProvider對應的Uri(相當於為該ContentProvider分配一個網域名稱)                android:exported="true"/>                                                                //指定該ContentProvider是否允許其他應用調用("true"為允許)升華筆記2:注釋1:ContentProvider子類實現的query()、insert()、update()和delete()方法,並不是給A應用本身調用,而是提供給其他應用來調用。注釋2:由於可以有多個應用程式通過ContentProvider暴露自己資料,android:authorities的作用在於方便其他應用程式訪問、刪除指定應用程式資料。
注釋3:傳遞參數-ContentResolver調用方法時的參數,將會傳遞給Uri對應的ContentProvider的query()、insert()、update()和delete()方法;            返回值   -ContentResolver調用方法時的返回值,即為Uri對應的ContentProvider的query()、insert()、update()和delete()方法的返回值;2.ContentResolver開發思路(B應用訪問、修改A應用的資料)(1)擷取ContentResolver執行個體對象。(2)通過執行個體對象調用ContentResolver的query()、insert()、update()和delete()方法。即指定Uri對應ContentProvider的query()、insert()、update()和delete()方法將要完成的功能。 四、實戰源碼 1.開發ContentProvider(1)FirstProvider.java
package com.example.android_contentprovider_1;import android.content.ContentProvider;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;public class FirstProvider extends ContentProvider { //1.第一次建立該ContentProvider時調用該方法 @Override public boolean onCreate() {  System.out.println("====onCreate方法被調用=====");  return false; } //2.實現查詢方法,該方法應該返回查詢得到的Cursor @Override public Cursor query(Uri uri, String[] projection, String where,   String[] selectionArgs, String sortOrder) {  System.out.println("====query方法被調用=====");  System.out.println("where參數為:"+where);  return null; } //3.該方法的傳回值代表了該ContentProvider所提供資料的MIME類型 @Override public String getType(Uri uri) {  return null; } //4.實現插入的方法,該方法應該返回新插入的記錄的Uri @Override public Uri insert(Uri uri, ContentValues values) {  System.out.println(uri+"====insert被調用=====");  System.out.println("values參數為:"+values);  return null; } //5.實現刪除方法,該方法應該返回被刪除的記錄條數 @Override public int delete(Uri uri, String where, String[] selectionArgs) {  System.out.println(uri+"====delete方法被調用=====");  System.out.println("where參數為:"+where);  return 0; } //6.實現更新方法,該方法應該返回被更新的記錄條數 @Override public int update(Uri uri, ContentValues values, String selection,   String[] selectionArgs) {  System.out.println(uri+"====update方法被調用=====");  System.out.println("values參數為:"+values);  return 0; }}
(2)AndroidManifest.xml(部分)<application 
android:icon="@drawable/ic_launcher"> 
<!--註冊一個ContentProvider --> 
<provider 
android:name=".FirstProvider" 
android:authorities="com.example.android_contentprovider_1" 
android:exported="true"/> 
</application> 
</manifest>
2.使用ContentResolver調用方法FirstResolver.java
package com.example.android_contentresolver_2;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.view.View;import android.widget.Toast;public class FirstResolver extends Activity { ContentResolver contentResolver; Uri uri=Uri.parse("content://com.example.android_contentprovider_1");//解析一個uri用以擷取對應的ContentProvider @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.main); //1.擷取系統的ContentResolver對象  contentResolver=getContentResolver(); } //2.調用ContentResolver的query()方法 public void query(View source) {  Cursor c=contentResolver.query(uri, null, "query_where", null, null);//實際返回的是該Uri對應的ContentProvider的query()的傳回值  Toast.makeText(this, "遠程ContentProvider返回的Cursor為"+c, Toast.LENGTH_SHORT).show(); } //3.調用ContentResolver的insert()方法 public void insert(View source) {  ContentValues values=new ContentValues();  values.put("name", "jiangdongguo");  Uri newUri=contentResolver.insert(uri, values);//將索引值對插入到uri對應的ContentProvider共用資料中  Toast.makeText(this, "遠程ContentProvider新插入記錄的Uri為:"+newUri, Toast.LENGTH_SHORT).show(); } //4.調用ContentResolver()的update()方法 public void update(View source) {  ContentValues values=new ContentValues();  values.put("name", "zhongxian");  int count=contentResolver.update(uri, values, "update_where", null);  Toast.makeText(this, "遠程ContentProvider更新記錄數為:"+count, Toast.LENGTH_SHORT).show(); } //5.調用ContentResoler的delete()方法 public void delete(View source) {  int count=contentResolver.delete(uri, "delete_where", null);//實際返回的是該ContentProvider的delete()的傳回值  Toast.makeText(this, "遠程ContentProvider刪除記錄數為:"+count, Toast.LENGTH_SHORT).show(); } }

注釋:布局介面為4個按鈕,每個按鈕需要定義android:onClick="delete"屬性。(1)ContentProvider不同於Activity存在複雜的聲明周期,ContentProvider只有一個onCreate()生命週期方法,當其他應用通過ContentResolver第一次訪問該ContentProvider時,onCreate()方法將會被回調,onCreate方法只會被調用一次。(2)其他應用通過ContentResolver調用query()、insert()、delete()、update()方法,實際上是調用ContentProvider提供的query()、insert()、delete()、update()方法來操作ContentProvider暴露的資料;(3)開發ContentProvider時所實現的query()、insert()、delete()、update()方法的第一個參數為Uri參數,該參數由ContentResolver調用這些方法時傳入。 效果示範: 

參考:http://wear.techbrood.com/reference/android/content/ContentProvider.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.