原文:http://developer.android.com/training/sync-adapters/creating-stub-provider.html
Sync Adapter 框架是設(shè)計(jì)成用來(lái)和設(shè)備數(shù)據(jù)一起工作的按摘,而這些設(shè)備數(shù)據(jù)應(yīng)該被靈活且安全的 Content Provider 框架管理划栓。因此名斟,Sync Adapter 框架會(huì)期望應(yīng)用已經(jīng)為它的本地?cái)?shù)據(jù)定義了 Content Provider锯蛀。如果 Sync Adapter 框架嘗試去運(yùn)行我們的 Sync Adapter扭仁,而我們的應(yīng)用沒有一個(gè) Content Provider 的話致稀,那么 Sync Adapter 將會(huì)崩潰宗苍。
如果我們正在開發(fā)一個(gè)新的應(yīng)用,它將數(shù)據(jù)從服務(wù)器傳輸?shù)揭慌_(tái)設(shè)備上佃却,那么我們務(wù)必考慮將本地?cái)?shù)據(jù)存儲(chǔ)于 Content Provider 中者吁。除了它對(duì)于 Sync Adapter 的重要性之外,Content Provider 還可以提供許多安全上的好處饲帅,更何況它是專門為了在 Android 設(shè)備上處理數(shù)據(jù)存儲(chǔ)而設(shè)計(jì)的复凳。要學(xué)習(xí)如何創(chuàng)建一個(gè) Content Provider瘤泪,可以閱讀:Creating a Content Provider。
然而育八,如果我們已經(jīng)通過別的形式來(lái)存儲(chǔ)本地?cái)?shù)據(jù)对途,我們?nèi)匀豢梢允褂?Sync Adapter 來(lái)處理數(shù)據(jù)傳輸。為了滿足 Sync Adapter 框架對(duì)于 Content Provider 的要求髓棋,我們可以在應(yīng)用中添加一個(gè) Stub Content Provider实檀。一個(gè) Stub Content Provider 實(shí)現(xiàn)了 Content Provider 類,但是所有的方法都返回null或者0仲锄。如果我們添加了一個(gè) Stub Content Provider劲妙,那么無(wú)論數(shù)據(jù)存儲(chǔ)機(jī)制是什么湃鹊,我們都可以使用 Sync Adapter 來(lái)傳輸數(shù)據(jù)儒喊。
如果在我們的應(yīng)用中已經(jīng)有了一個(gè) Content Provider,那么我們就不需要?jiǎng)?chuàng)建 Stub Content Provider 了币呵。在這種情況下怀愧,我們可以略過這節(jié)課程,直接進(jìn)入:創(chuàng)建 Sync Adapter余赢。如果你還沒有創(chuàng)建 Content Provider芯义,這節(jié)課將向你展示如何通過添加一個(gè) Stub Content Provider,將你的 Sync Adapter 添加到框架中妻柒。
添加一個(gè) Stub Content Provider
要為我們的應(yīng)用創(chuàng)建一個(gè) Stub Content Provider扛拨,首先繼承ContentProvider類,并且在所有需要重寫的方法中举塔,我們一律不進(jìn)行任何處理而是直接返回绑警。下面的代碼片段展示了我們應(yīng)該如何創(chuàng)建一個(gè) Stub Content Provider:
/*
* Define an implementation of ContentProvider that stubs out
* all methods
*/publicclassStubProviderextendsContentProvider{/*
* Always return true, indicating that the
* provider loaded correctly.
*/@OverridepublicbooleanonCreate(){returntrue;? ? }/*
* Return an empty String for MIME type
*/@OverridepublicStringgetType(){returnnewString();? ? }/*
* query() always returns no results
*
*/@OverridepublicCursorquery(
Uri uri,
String[] projection,
String selection,
String[] selectionArgs,
String sortOrder){returnnull;? ? }/*
* insert() always returns null (no URI)
*/@OverridepublicUriinsert(Uri uri, ContentValues values){returnnull;? ? }/*
* delete() always returns "no rows affected" (0)
*/@Overridepublicintdelete(Uri uri, String selection, String[] selectionArgs){return0;? ? }/*
* update() always returns "no rows affected" (0)
*/publicintupdate(
Uri uri,
ContentValues values,
String selection,
String[] selectionArgs){return0;? ? }}
在 Manifest 清單文件中聲明 Provider
Sync Adapter 框架會(huì)通過查看應(yīng)用的 manifest 文件中是否聲明了 provider,來(lái)驗(yàn)證我們的應(yīng)用是否使用了 Content Provider央渣。為了在 manifest 清單文件中聲明我們的 Stub Content Provider计盒,添加一個(gè)標(biāo)簽,并讓它擁有下列屬性字段:
android:name="com.example.android.datasync.provider.StubProvider"
指定實(shí)現(xiàn) Stub Content Provider 類的完整包名芽丹。
android:authorities="com.example.android.datasync.provider"
指定 Stub Content Provider 的 URI Authority北启。用應(yīng)用的包名加上字符串".provider"作為該屬性字段的值。雖然我們?cè)谶@里向系統(tǒng)聲明了 Stub Content Provider拔第,但是不會(huì)嘗試訪問 Provider 本身咕村。
android:exported="false"
確定其它應(yīng)用是否可以訪問 Content Provider。對(duì)于 Stub Content Provider 而言蚊俺,由于沒有讓其它應(yīng)用訪問該 Provider 的必要培廓,所以我們將該值設(shè)置為false。該值并不會(huì)影響 Sync Adapter 框架和 Content Provider 之間的交互春叫。
android:syncable="true"
該標(biāo)識(shí)指明 Provider 是可同步的肩钠。如果將這個(gè)值設(shè)置為true泣港,那么將不需要在代碼中調(diào)用setIsSyncable()。這一標(biāo)識(shí)將會(huì)允許 Sync Adapter 框架和 Content Provider 進(jìn)行數(shù)據(jù)傳輸价匠,但是僅僅在我們顯式地執(zhí)行相關(guān)調(diào)用時(shí)当纱,這一傳輸時(shí)才會(huì)進(jìn)行。
下面的代碼片段展示了我們應(yīng)該如何將標(biāo)簽添加到應(yīng)用的 manifest 清單文件中:
......
現(xiàn)在我們已經(jīng)創(chuàng)建了所有 Sync Adapter 框架所需要的依賴項(xiàng)踩窖,接下來(lái)我們可以創(chuàng)建封裝數(shù)據(jù)傳輸代碼的組件了坡氯。該組件就叫做 Sync Adapter。在下節(jié)課中洋腮,我們將會(huì)展示如何將這一組件添加到應(yīng)用中箫柳。