一 ContentProvider
- 內(nèi)容提供者(ContentProvider)是Android系統(tǒng)四大組件之一,它是不同應(yīng)用程序之間進(jìn)行數(shù)據(jù)共享的標(biāo)準(zhǔn)API,通過(guò)ContentResolver類可以訪問(wèn)ContentProvider中共享的數(shù)據(jù)。
- ContentProvider的工作原理如下:
- A程序使用ContetntProvider暴露數(shù)據(jù),才能被其他程序操作。B程序通過(guò)ContetnResolver操作A程序暴露出來(lái)的數(shù)據(jù),A程序?qū)⒉僮鞯慕Y(jié)果返回給ContentResoler,然后ContetnResolver再將操作的結(jié)果返回給B程序。
1.1 數(shù)據(jù)模型- ContentProvider 使用基于數(shù)據(jù)庫(kù)模型的簡(jiǎn)單表格來(lái)提供需要共享的數(shù)據(jù),在該表格中,每一表示一條記錄,而每一列代表特定類型和含義的數(shù)據(jù),并且其中每一條數(shù)據(jù)記錄都包含一個(gè)名為“_ID”的字段類標(biāo)識(shí)每條數(shù)據(jù)。
1.2 Uri(統(tǒng)一資源標(biāo)識(shí)符)
- 統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier,或URI)是一個(gè)用于標(biāo)識(shí)某一資源名稱的字符串。 該標(biāo)識(shí)允許用戶對(duì)任何(包括本地和互聯(lián)網(wǎng))的資源通過(guò)特定的協(xié)議進(jìn)行交互操作。
- ContentResolver提供一系列增刪改查的方法對(duì)數(shù)據(jù)進(jìn)行操作,并且這些方法以Uri的形式對(duì)外提供數(shù)據(jù)。
- Uri為內(nèi)容提供者中的數(shù)據(jù)建立了唯一標(biāo)識(shí)符。它主要由三部分組成,scheme、authorities和path。
1.3 創(chuàng)建內(nèi)容提供者
內(nèi)容提供者創(chuàng)建步驟:
- 在程序包名處右擊選擇【New】->【Other】->【Content Provider】選項(xiàng)
- 輸入內(nèi)容提供者的Class Name(類名稱)和URI Authorities(唯一標(biāo)識(shí),通常使用包名)
- 點(diǎn)擊【Finish】按鈕創(chuàng)建完成
private class MyObserver extends ContentObserver{
public MyObserver(Handler handler) {
super(handler);
}
public void onChange(boolean selfChange) {
super.onChange(selfChange);
}
//還需要重寫增刪改查的方法
//...
}
1.4 清單文件
- 內(nèi)容提供者創(chuàng)建完成后,Android Studio會(huì)自動(dòng)在AndroidManifest.xml中對(duì)內(nèi)容提供者進(jìn)行注冊(cè)。
<application ......>
<provider
android:name=".MyContentProvider"
android:authorities="cn.itcast.mycontentprovider"
android:enabled="true"
android:exported="true" >
</provider>
</application>
- provider中的android:name代表是繼承于ContentProvider類的的全路徑名稱。
-
android:authorities
:標(biāo)識(shí)MyContentProvider
提供的數(shù)據(jù),該值可以是一個(gè)或者多個(gè)URI authority,authorities之間用分號(hào)隔開。 -
android:enabled
:標(biāo)識(shí)MyContentProvider
提供的數(shù)據(jù)能否被系統(tǒng)實(shí)例化 -
android:exported
:用于指示該服務(wù)是否能被其他程序應(yīng)用組件調(diào)用或跟他交互; 取值為(true | false),如果設(shè)置成true,則能夠被調(diào)用或交互,否則不能;設(shè)置為false時(shí),只有同一個(gè)應(yīng)用程序的組件或帶有相同用戶ID的應(yīng)用程序才能啟動(dòng)或綁定該服務(wù)。
1.5 訪問(wèn)其他程序的數(shù)據(jù)
- 在不同的應(yīng)用程序之間交換數(shù)據(jù)時(shí),應(yīng)用程序會(huì)通過(guò)ContentProvider暴露自身數(shù)據(jù),便通過(guò)ContentResolver對(duì)程序暴露的數(shù)據(jù)進(jìn)行操作,因此 CntentProvider充當(dāng)一個(gè)中介的角色。由于在使用ContentProvider暴露數(shù)據(jù)時(shí),提供了相應(yīng)的 Uri,因此在訪問(wèn)現(xiàn)有的CntentProvider時(shí),要指定相應(yīng)的 Uri,然后再通過(guò)ContentResolver對(duì)象來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)的操作。
1.5.1 訪問(wèn)提供者【了解】
- 從Uri訪問(wèn) ContentProvider 的常用模式是使用 CursorLoader 在后臺(tái)運(yùn)行異步查詢。UI中的 Activity 或 Fragment 會(huì)調(diào)用查詢的 CursorLoader,其轉(zhuǎn)而使用 ContentResolver 獲取 ContentProvider。如此一來(lái),用戶便可在查詢運(yùn)行時(shí)繼續(xù)使用UI。
- ContentResolver對(duì)象在客戶 app的進(jìn)程中,ContentProvider對(duì)象在app中,它們之間自動(dòng)處理IPC。ContentProvider也是數(shù)據(jù)存儲(chǔ)同數(shù)據(jù)的外在表現(xiàn)的一個(gè)抽象層。
- 注意:為了存取provider,app通常在它的manifest文件中請(qǐng)求特定的權(quán)限。
- 例如,為了從User Dictionary Provider中得到一個(gè)單詞表,你需要調(diào)用ContentResolver.query()。query()方法實(shí)際調(diào)用User Dictionary Provider中的ContentProvider.query(),如下:
// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows
- 下表顯示了query的參數(shù)同SQL SELECT語(yǔ)句的對(duì)應(yīng)關(guān)系:
1.5.2 通過(guò)ContentProvider查詢其他程序數(shù)據(jù)
- 步驟:
- 通過(guò)parse()方法解析Uri
- 通過(guò)query()方法查詢數(shù)據(jù)
- 通過(guò)while()遍歷查詢到的數(shù)據(jù)
//獲取相應(yīng)操作的Uri,Uri.parse()方法是將字符串轉(zhuǎn)化成Uri對(duì)象。
Uri uri = Uri.parse("content://cn.itcast.mycontentprovider/person");
//獲取ContentResolver對(duì)象
ContentResolver resolver = context.getContentResolver();
//通過(guò)ContentResolver對(duì)象查詢數(shù)據(jù)
Cursor cursor = resolver.query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder);
//通過(guò)while()循環(huán)將Cursor對(duì)象中的數(shù)據(jù)遍歷出來(lái)
while (cursor.moveToNext()) {
String address = cursor.getString(0);
long date = cursor.getLong(1);
int type = cursor.getInt(2);
}
cursor.close();
1.5.3 query方法
ContentResolver的query方法的函數(shù)接口如下:
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
參數(shù)說(shuō)明:
- uri:要查詢的數(shù)據(jù)的地址。
- projection:要查詢的列,即需要返回的數(shù)據(jù)的字段。
- selection:查詢條件,即需要滿足的約束條件。
- selectionArgs:查詢條件的參數(shù),用于替換selection中的占位符。
- sortOrder:查詢結(jié)果的排序方式。
- cancellationSignal:用于取消查詢的信號(hào)。
返回值:
- Cursor:查詢結(jié)果的游標(biāo)對(duì)象。
注意事項(xiàng):
- 如果查詢不需要使用selection和selectionArgs,可以將它們?cè)O(shè)置為null。
- 如果不需要排序,可以將sortOrder設(shè)置為null。
- 如果不需要取消查詢,可以將cancellationSignal設(shè)置為null。
示例代碼:
Uri uri = Uri.parse("content://com.example.provider/user");
String[] projection = {"name", "age"};
String selection = "age > ?";
String[] selectionArgs = {"18"};
String sortOrder = "name ASC";
CancellationSignal cancellationSignal = null;
Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
1.5.4 多學(xué)一招:UriMatcher類【了解】
- 初始化UriMatcher
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
- 將Uri注冊(cè)到UriMatcher中
matcher.addURI("cn.itcast.contentprovider", "people", PEOPLE); matcher.addURI("cn.itcast.contentprovider", "person/#", PEOPLE_ID);
- 與已經(jīng)注冊(cè)的Uri進(jìn)行匹配
Uri uri = Uri.parse("content://" + "cn.itcast.contentprovider" + "/people");
int match = matcher.match(uri);
switch (match){
case PEOPLE:
//匹配成功后做的相關(guān)操作
case PEOPLE_ID:
//匹配成功后做的相關(guān)操作
default:
return null;
}
二 ContentObserver
- 內(nèi)容觀察者(ContentObserver)用于觀察指定Uri所代表的數(shù)據(jù)的變化,當(dāng)ContentObserver觀察到指定Uri代表的數(shù)據(jù)發(fā)生變化時(shí),就會(huì)觸發(fā)onChange()方法,此時(shí)在onChange()方法中使用ContentResovler可以查詢到變化的數(shù)據(jù)。
- 要使用ContentObserver觀察數(shù)據(jù)變化,就必須在ContentProvider中調(diào)用ContentResolver的notifyChange()方法。
- ContentObserver的工作原理如下:
- 使用contentObserver觀察 A程序的數(shù)據(jù)時(shí),首先要在 A程序的ContentProvider中調(diào)用ContentResolver的notifyChange()方法,調(diào)用此方法后,當(dāng) B操作程序作 A程序中的數(shù)據(jù)時(shí), A程序會(huì)向消息中心發(fā)送數(shù)據(jù)變化的消息。此時(shí)C程序會(huì)觀察到消息中心的數(shù)據(jù)有變化,會(huì)觸發(fā) ContentObserver的onChange()方法。
創(chuàng)建ContentObserver的具體步驟如下:
- 使用contentObserver觀察 A程序的數(shù)據(jù)時(shí),首先要在 A程序的ContentProvider中調(diào)用ContentResolver的notifyChange()方法,調(diào)用此方法后,當(dāng) B操作程序作 A程序中的數(shù)據(jù)時(shí), A程序會(huì)向消息中心發(fā)送數(shù)據(jù)變化的消息。此時(shí)C程序會(huì)觀察到消息中心的數(shù)據(jù)有變化,會(huì)觸發(fā) ContentObserver的onChange()方法。
2.1 創(chuàng)建ContentObserver
- 創(chuàng)建一個(gè)類繼承自ContentObserver,并重寫onChange方法。
public class MyContentObserver extends ContentObserver { //Handler對(duì)象是主線程中的Handler對(duì)象,也可以是其他線程中的Handler對(duì)象 public MyContentObserver(Handler handler) { super(handler); } //當(dāng)MyContentObserver觀察到Uri代表的數(shù)據(jù)發(fā)生變化時(shí),程序回調(diào)用onChange()方法,并在該方法中處理相關(guān)的邏輯 @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); // 處理數(shù)據(jù)變化的邏輯 } }
- 注冊(cè)內(nèi)容觀察者
ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://aaa.bbb.ccc"); resolver.registerContentObserver(uri, true, new MyContentObserver(new Handler());
參數(shù)說(shuō)明:
- uri:要監(jiān)聽的數(shù)據(jù)的地址。
- notifyForDescendants:是否監(jiān)聽uri的所有子路徑。
- 取消注冊(cè)內(nèi)容觀察者
getContentResolver().unregisterContentObserver(contentObserver);
通過(guò)以上步驟,就可以創(chuàng)建并使用ContentObserver來(lái)監(jiān)聽數(shù)據(jù)的變化。
注意事項(xiàng):
- ContentObserver只能監(jiān)聽ContentProvider中數(shù)據(jù)的變化,而不能監(jiān)聽其他的數(shù)據(jù)源。
- ContentObserver的onChange方法在主線程中執(zhí)行,如果需要執(zhí)行耗時(shí)操作,建議在onChange中開啟新的線程來(lái)處理。
- ContentObserver的注冊(cè)和取消注冊(cè)應(yīng)該在合適的時(shí)機(jī)進(jìn)行,避免不必要的資源消耗。
-
下面是一個(gè)完整的示例代碼,演示如何創(chuàng)建和使用ContentObserver來(lái)監(jiān)聽數(shù)據(jù)的變化:
public class MainActivity extends AppCompatActivity { private MyContentObserver contentObserver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 創(chuàng)建ContentObserver對(duì)象 contentObserver = new MyContentObserver(new Handler()); // 注冊(cè)ContentObserver監(jiān)聽數(shù)據(jù)變化 Uri uri = Uri.parse("content://com.example.provider/user"); getContentResolver().registerContentObserver(uri, true, contentObserver); } @Override protected void onDestroy() { super.onDestroy(); // 取消注冊(cè)ContentObserver getContentResolver().unregisterContentObserver(contentObserver); } private class MyContentObserver extends ContentObserver { public MyContentObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); // 處理數(shù)據(jù)變化的邏輯 Log.d("ContentObserver", "Data changed: " + uri.toString()); // 可以在這里更新UI或執(zhí)行其他操作 } } }
- 在上述示例中,在MainActivity的onCreate方法中創(chuàng)建了一個(gè)ContentObserver對(duì)象,并在onDestroy方法中取消注冊(cè)。在MyContentObserver的onChange方法中,我們可以處理數(shù)據(jù)變化的邏輯,例如打印日志或更新UI。
2.2 補(bǔ)充:注冊(cè)ContetnObserver的時(shí)機(jī)
- 通常是在Activity、Fragment或Service等組件中的某個(gè)方法中注冊(cè)ContentObserver來(lái)監(jiān)聽數(shù)據(jù)的變化。具體來(lái)說(shuō),可以在以下方法中注冊(cè)ContentObserver:
- 在Activity中,可以在onCreate方法中注冊(cè),然后在onDestroy方法中取消注冊(cè)。
- 在Fragment中,可以在onCreateView方法中注冊(cè),然后在onDestroyView方法中取消注冊(cè)。
- 在Service中,可以在onCreate方法中注冊(cè),然后在onDestroy方法中取消注冊(cè)。
- 具體選擇,取決于業(yè)務(wù)需求和組件的生命周期。
- 示例代碼:
public class MainActivity extends AppCompatActivity {
private MyContentObserver contentObserver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 創(chuàng)建ContentObserver對(duì)象
contentObserver = new MyContentObserver(new Handler());
// 注冊(cè)ContentObserver監(jiān)聽數(shù)據(jù)變化
Uri uri = Uri.parse("content://com.example.provider/user");
getContentResolver().registerContentObserver(uri, true, contentObserver);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 取消注冊(cè)ContentObserver
getContentResolver().unregisterContentObserver(contentObserver);
}
private class MyContentObserver extends ContentObserver {
public MyContentObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
// 處理數(shù)據(jù)變化的邏輯
Log.d("ContentObserver", "Data changed: " + uri.toString());
// 可以在這里更新UI或執(zhí)行其他操作
}
}
}
三 題目總結(jié)
- 簡(jiǎn)述內(nèi)容提供者的工作原理
- 假設(shè)B程序需要操作A程序數(shù)據(jù)庫(kù)中的數(shù)據(jù),一般需要A程序使用ContentProvider
暴露數(shù)據(jù),才能被其他程序操作。B程序通過(guò)ContentResolver操作A程序暴露出來(lái)的數(shù)據(jù),而A程序會(huì)將操作結(jié)果返回給ContentResolver,然后ContentResolver再將操作結(jié)果返回給B程序。
- 假設(shè)B程序需要操作A程序數(shù)據(jù)庫(kù)中的數(shù)據(jù),一般需要A程序使用ContentProvider
- 簡(jiǎn)述內(nèi)容觀察者的工作原理
- 使用ContentObserver觀察A程序的數(shù)據(jù)時(shí),首先要在A程序的ContentProvider中調(diào)用ContentResolver的notifyChange()方法。調(diào)用此方法后,當(dāng)B程序操作A程序中的數(shù)據(jù)時(shí),A程序會(huì)向“消息中心”發(fā)送數(shù)據(jù)變化的消息,此時(shí)C程序會(huì)觀察到“消息中心”的數(shù)據(jù)有變化,會(huì)觸發(fā)ContentObserver的onChange()方法。
- 在ContentProvider中ContentUris的作用是提供增刪改查的方法
- 在ContentProvider中,ContentUris類提供了一些方法,用于處理操作數(shù)據(jù)庫(kù)中的數(shù)據(jù)的URI。這些方法可以幫助開發(fā)者在增刪改查數(shù)據(jù)時(shí),對(duì)URI進(jìn)行解析和操作。
具體來(lái)說(shuō),ContentUris的作用如下:
- 解析URI:ContentUris類的parseId()方法可以從URI中解析出對(duì)應(yīng)的記錄的ID。這個(gè)方法通常在查詢或刪除單個(gè)記錄時(shí)使用。例如,可以使用ContentUris.parseId(uri)方法從URI中解析出記錄的ID。
- 構(gòu)建URI:ContentUris類的withAppendedId()方法可以將ID添加到URI中,構(gòu)建出一個(gè)新的URI。這個(gè)方法通常在插入或更新記錄時(shí)使用。例如,可以使用ContentUris.withAppendedId(baseUri, id)方法將ID添加到baseUri中,構(gòu)建出新的URI。
- 獲取記錄的URI:ContentUris類的withAppendedId()方法也可以用于獲取指定記錄的URI。這個(gè)方法通常在查詢或刪除單個(gè)記錄時(shí)使用。例如,可以使用ContentUris.withAppendedId(baseUri, id)方法獲取指定記錄的URI。
通過(guò)使用ContentUris類的方法,開發(fā)者可以方便地解析和操作URI,從而實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增刪改查的操作。
- 若要實(shí)現(xiàn)對(duì)系統(tǒng)聯(lián)系人的增刪改查,需要使用的系統(tǒng)ContentProvider的Uri為Contacts.Phones.CONTENT_URI
- 聯(lián)系人信息內(nèi)容提供者的主機(jī)名是com.android.contacts
- 聯(lián)系人信息的內(nèi)容提供者的主機(jī)名是
com.android.contacts
,它是Android系統(tǒng)中默認(rèn)的聯(lián)系人信息提供者。通過(guò)該內(nèi)容提供者,應(yīng)用程序可以訪問(wèn)和操作設(shè)備上的聯(lián)系人信息。
- 聯(lián)系人信息的內(nèi)容提供者的主機(jī)名是
- 下面哪些功能需要用ContentProvider來(lái)實(shí)現(xiàn)()。
A、讀取系統(tǒng)中的短信內(nèi)容
B、建立一個(gè)數(shù)據(jù)庫(kù)
C、開機(jī)后自動(dòng)啟動(dòng)一個(gè)程序
D、播放一段音樂
-
解析:
-
A、讀取系統(tǒng)中的短信內(nèi)容:需要使用ContentProvider來(lái)實(shí)現(xiàn)。Android系統(tǒng)中的短信內(nèi)容存儲(chǔ)在短信提供者中,開發(fā)者需要通過(guò)ContentResolver來(lái)查詢短信提供者,從而讀取系統(tǒng)中的短信內(nèi)容。
-
B、建立一個(gè)數(shù)據(jù)庫(kù):不需要使用ContentProvider來(lái)實(shí)現(xiàn)。建立數(shù)據(jù)庫(kù)可以直接使用SQLiteOpenHelper或Room等數(shù)據(jù)庫(kù)框架來(lái)創(chuàng)建和管理數(shù)據(jù)庫(kù)。
-
C、開機(jī)后自動(dòng)啟動(dòng)一個(gè)程序:不需要使用ContentProvider來(lái)實(shí)現(xiàn)。開機(jī)后自動(dòng)啟動(dòng)一個(gè)程序可以通過(guò)BroadcastReceiver和BOOT_COMPLETED廣播來(lái)實(shí)現(xiàn)。
-
D、播放一段音樂:不需要使用ContentProvider來(lái)實(shí)現(xiàn)。播放音樂可以使用MediaPlayer或其他音頻播放框架來(lái)實(shí)現(xiàn),不涉及ContentProvider的使用。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-498536.html
-
因此,只有讀取系統(tǒng)中的短信內(nèi)容需要使用ContentProvider來(lái)實(shí)現(xiàn)。其他功能不需要使用ContentProvider。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-498536.html
-
- 短信的內(nèi)容提供者是()
A、ContactProvider
B、MessageProvider
C、SmsProvider
D、TelephonyProvider - 在下列選項(xiàng)中,聯(lián)系人信息內(nèi)容提供者的主機(jī)名是()
A、contact
B、com.android.contacts
C、com.android.provider.contact
D、com.android.provider.contacts - 內(nèi)容提供者主要功能是實(shí)現(xiàn)跨程序共享數(shù)據(jù)的功能
- provider中的android:name代表是繼承于ContentProvider類的的全路徑名稱。
- 為了解析Uri對(duì)象,Android系統(tǒng)提供了一個(gè)輔助工具類UriMatcher用于匹配Uri。
- Android中通過(guò)ContentResover.query()查詢短信數(shù)據(jù)庫(kù)的時(shí)候,第一個(gè)Uri參數(shù)如何寫 contentprovider
- 內(nèi)容觀察者是通過(guò)觀察消息中心來(lái)觀察數(shù)據(jù)庫(kù)的變化
- 消息中心是用來(lái)觀察指定Uri所代表的數(shù)據(jù)
- 利用內(nèi)容解析者讀取短信數(shù)據(jù)庫(kù)內(nèi)容時(shí),短信數(shù)據(jù)庫(kù)SmsInfo表主要用來(lái)存儲(chǔ)短信信息
- resolver.registerContentObserver()方法用于注冊(cè)內(nèi)容觀察者
- 創(chuàng)建UriMatcher對(duì)象時(shí)調(diào)用
UriMatcher(int code)
,參數(shù)通常使用UriMatcher.NO_MATCH
,表示路徑不滿足條件返回_-1 - 當(dāng)ContentObserver觀察到指定Uri代表的數(shù)據(jù)發(fā)生變化時(shí),就會(huì)觸發(fā)ContentObserver的**onChange()**方法。
- 內(nèi)容提供者把私有的數(shù)據(jù)給暴露出來(lái),我們通過(guò)ContentResolver來(lái)進(jìn)行查詢數(shù)據(jù)
- 在Android中,是通過(guò)ContentResolver讀取聯(lián)系人信息的。
- 注冊(cè)provider時(shí)需要指定兩個(gè)屬性android.name和android:authorities
- 短信數(shù)據(jù)是存放在sms表中的
- Android中通過(guò)內(nèi)容提供者來(lái)讀取聯(lián)系人信息,data表用來(lái)保存聯(lián)系人信息的.
- Android中讀取聯(lián)系人信息 有三張關(guān)鍵的表1 data表用來(lái)存儲(chǔ)聯(lián)系人信息的表,2 raw_contacts 表用來(lái)存儲(chǔ)一共有多少個(gè)聯(lián)系人. 3 mimetype表用來(lái)區(qū)分聯(lián)系人信息的表
- 在短信接收器案例中,注冊(cè)短信內(nèi)容觀察者時(shí),使用的到Uri是Content://sms/。
四 補(bǔ)充
- 請(qǐng)簡(jiǎn)要說(shuō)明 ContentProvider 對(duì)外共享數(shù)據(jù)的好處。
- 通過(guò) ContentProvider 共享數(shù)據(jù)統(tǒng)一數(shù)據(jù)訪問(wèn)方式,使用起來(lái)更規(guī)范,通過(guò)數(shù)據(jù)庫(kù)存儲(chǔ)并指定了 URI,只有通過(guò)特定 URI 才能訪問(wèn)數(shù)據(jù),使數(shù)據(jù)更安全。
- 請(qǐng)簡(jiǎn)要說(shuō)明 ContentProvider、ContentResolver 和 ContentObserver 之間的聯(lián)系。
- ContentProvider 可以共享自己的數(shù)據(jù)給外部應(yīng)用訪問(wèn),要訪問(wèn) ContentProvider 暴露的數(shù)據(jù)就要用到 ContentResolver。
- ContentObserver 就相當(dāng)于中間人的角色,它可以事實(shí)監(jiān)聽ContentProvider 的 數(shù) 據(jù) 是 否 發(fā) 生 變 化 , 如 果 發(fā) 生 變 化 就 會(huì) 觸 發(fā) onChange() 方 法 ,Contentresolver 可以在 onChange()方法中查詢的哪些數(shù)據(jù)發(fā)生了變化再對(duì)數(shù)據(jù)進(jìn)行操作。
到了這里,關(guān)于探索安卓?jī)?nèi)容提供者:構(gòu)建、訪問(wèn)和管理數(shù)據(jù)【復(fù)習(xí)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!