- Android Studio開發(fā)實戰(zhàn):從零基礎(chǔ)到App上線(第2版)
- 歐陽燊
- 2319字
- 2019-12-06 12:07:28
4.5 內(nèi)容提供與處理
本節(jié)介紹Android四大組件之一的ContentProvider的基本概念和常見用法。首先說明如何使用內(nèi)容提供器封裝數(shù)據(jù)的外部訪問接口;接著闡述如何通過內(nèi)容解析器在外部查詢和修改數(shù)據(jù),以及使用內(nèi)容操作器完成批量數(shù)據(jù)操作;然后說明內(nèi)容觀察器的應(yīng)用場合,并演示如何借助內(nèi)容觀察器實現(xiàn)流量校準的功能。
4.5.1 內(nèi)容提供器ContentProvider
Android號稱提供了4大組件,分別是頁面Activity、廣播Broadcast、服務(wù)Service和內(nèi)容提供器ContentProvider。其中內(nèi)容提供器是跟數(shù)據(jù)存取有關(guān)的組件,完整的內(nèi)容組件由內(nèi)容提供器ContentProvider、內(nèi)容解析器ContentResolver、內(nèi)容觀察器ContentObserver這三部分組成。
ContentProvider為App存取內(nèi)部數(shù)據(jù)提供統(tǒng)一的外部接口,讓不同的應(yīng)用之間得以共享數(shù)據(jù)。像我們熟知的SQLite操作的是應(yīng)用自身的內(nèi)部數(shù)據(jù)庫;文件的上傳和下載操作的是后端服務(wù)器的文件;而ContentProvider操作的是本設(shè)備其他應(yīng)用的內(nèi)部數(shù)據(jù),是一種中間層次的數(shù)據(jù)存儲形式。
在實際編碼中,ContentProvider只是一個服務(wù)端的數(shù)據(jù)存取接口,開發(fā)者需要在其基礎(chǔ)上實現(xiàn)一個具體類,并重寫以下相關(guān)數(shù)據(jù)庫管理方法。
- onCreate:創(chuàng)建數(shù)據(jù)庫并獲得數(shù)據(jù)庫連接。
- query:查詢數(shù)據(jù)。
- insert:插入數(shù)據(jù)。
- update:更新數(shù)據(jù)。
- delete:刪除數(shù)據(jù)。
- getType:獲取數(shù)據(jù)類型。
這些方法看起來是不是很像SQLite?沒錯,ContentProvider作為中間接口,本身并不直接保存數(shù)據(jù),而是通過SQLiteOpenHelper與SQLiteDatabase間接操作底層的SQLite。所以要想使用ContentProvider,首先得實現(xiàn)SQLite的數(shù)據(jù)表幫助類,然后由ContentProvider封裝對外的接口。
下面是使用ContentProvider提供用戶信息對外接口的代碼:


既然內(nèi)容提供器是四大組件之一,就得在AndroidManifest.xml中注冊它的定義,并開放外部訪問權(quán)限,注冊代碼如下:

注冊完畢后就完成了服務(wù)端App的封裝工作,接下來可由其他App進行數(shù)據(jù)存取。
4.5.2 內(nèi)容解析器ContentResolver
前面提到了利用ContentProvider實現(xiàn)服務(wù)端App的數(shù)據(jù)封裝,如果客戶端App想訪問對方的內(nèi)部數(shù)據(jù),就要通過內(nèi)容解析器ContentResolver訪問。內(nèi)容解析器是客戶端App操作服務(wù)端數(shù)據(jù)的工具,相對應(yīng)的內(nèi)容提供器是服務(wù)端的數(shù)據(jù)接口。要獲取ContentResolver對象,在Activity代碼中調(diào)用getContentResolver方法即可。
ContentResolver提供的方法與ContentProvider是一一對應(yīng)的,比如query、insert、update、delete、getType等方法,連方法的參數(shù)類型都一模一樣。其中,最常用的是query函數(shù),調(diào)用該函數(shù)返回一個游標Cursor對象,這個游標與SQLite的游標是一樣的,想必讀者早已用得爐火純青。
下面是query方法的具體參數(shù)說明(依順序排列)。
- uri:Uri類型,可以理解為本次操作的數(shù)據(jù)表路徑。
- projection:字符串?dāng)?shù)組類型,指定將要查詢的字段名稱列表。
- selection:字符串類型,指定查詢條件。
- selectionArgs:字符串?dāng)?shù)組類型,指定查詢條件中的參數(shù)取值列表。
- sortOrder:字符串類型,指定排序條件。
針對前面UserInfoProvider提供的數(shù)據(jù)接口,下面使用ContentResolver在客戶端添加用戶信息,代碼如下:

下面是使用ContentResolver在客戶端查詢所有用戶信息的代碼:

添加用戶信息的效果如圖4-19所示,一開始服務(wù)端的用戶表不存在用戶記錄,客戶端使用ContentResolver添加一條記錄后,服務(wù)端的用戶記錄數(shù)返回1。用戶信息的查詢明細如圖4-20所示,點擊頁面上的用戶記錄數(shù)量文字,彈出一個對話框,提示當(dāng)前找到的所有用戶的明細數(shù)據(jù),包括姓名、年齡、身高、體重等信息。

圖4-19 利用內(nèi)容提供器添加用戶信息

圖4-20 利用內(nèi)容解析器查詢獲得用戶信息
在實際開發(fā)中,普通App很少會開放數(shù)據(jù)接口給其他應(yīng)用訪問,作為服務(wù)端接口的ContentProvider基本用不到。內(nèi)容組件能夠派上用場的情況往往是App想要訪問系統(tǒng)應(yīng)用的通信數(shù)據(jù),比如查看聯(lián)系人、短信、通話記錄,以及對這些通信信息進行增、刪、改、查。
下面是使用ContentResolver添加聯(lián)系人信息的代碼片段,此時訪問的數(shù)據(jù)來源變成了系統(tǒng)自帶的raw_contacts:

注意上述代碼用了4條insert語句,但業(yè)務(wù)上只添加了一個聯(lián)系人信息。這樣處理有一個問題,就是4個insert操作不在同一個事務(wù)中,要是中間某步insert操作失敗,那么之前插入成功的記錄就無法自動回滾,從而產(chǎn)生垃圾數(shù)據(jù)。
為了避免這種情況的發(fā)生,Android提供了內(nèi)容操作器ContentProviderOperation進行批量數(shù)據(jù)的處理,即在一個請求中封裝多條記錄的修改動作,然后一次性提交給服務(wù)端,從而實現(xiàn)在一個事務(wù)中完成多條數(shù)據(jù)的更新操作。即使某條記錄處理失敗,ContentProviderOperation也能根據(jù)事務(wù)一致性原則自動回滾本事務(wù)已經(jīng)執(zhí)行的修改操作。
下面是使用ContentProviderOperation批量添加聯(lián)系人信息的代碼片段:

添加聯(lián)系人信息的效果如圖4-21和圖4-22所示。其中,圖4-21所示為添加之前的截圖,此時聯(lián)系人個數(shù)為157位;圖4-22所示為添加成功之后的截圖,此時聯(lián)系人個數(shù)為158位。

圖4-21 聯(lián)系人添加之前的界面

圖4-22 聯(lián)系人添加之后的界面
4.5.3 內(nèi)容觀察器ContentObserver
ContentResolver獲取數(shù)據(jù)采用的是主動查詢方式,有查詢就有數(shù)據(jù),沒查詢就沒數(shù)據(jù)。有時我們不但要獲取以往的數(shù)據(jù),還要實時獲取新增的數(shù)據(jù),最常見的業(yè)務(wù)場景是短信驗證碼。電商App經(jīng)常在用戶注冊或付款時發(fā)送驗證碼短信,為了給用戶省事,App通常會監(jiān)控手機剛收到的驗證碼數(shù)字,并自動填入驗證碼輸入框。這時就用到了內(nèi)容觀察器ContentObserver,給目標內(nèi)容注冊一個觀察器,目標內(nèi)容的數(shù)據(jù)一旦發(fā)生變化,觀察器規(guī)定好的動作馬上觸發(fā),從而執(zhí)行開發(fā)者預(yù)先定義的代碼。
內(nèi)容觀察器的用法與內(nèi)容提供器類似,也要從ContentObserver派生一個觀察器類,然后通過ContentResolver對象調(diào)用相應(yīng)的方法注冊或注銷觀察器。下面是ContentResolver與觀察器有關(guān)的方法說明。
- registerContentObserver:注冊內(nèi)容觀察器。
- unregisterContentObserver:注銷內(nèi)容觀察器。
- notifyChange:通知內(nèi)容觀察器發(fā)生了數(shù)據(jù)變化。
為了讓讀者更好理解,下面舉一個實際應(yīng)用的例子。手機號碼的每月流量限額一般由用戶手動配置,但流量限額其實是由移動運營商指定的。以中國移動為例,只要發(fā)送流量校準短信給運營商客服號碼(如發(fā)送18到10086),運營商就會給用戶發(fā)送本月的流量數(shù)據(jù),包括月流量額度、已使用流量、未使用流量等信息。手機App只需監(jiān)控10086發(fā)送的短信內(nèi)容,即可自動獲取手機號碼的月流量額度,無須用戶手工配置。
下面是利用ContentObserver實現(xiàn)流量校準的代碼片段:


流量校準的效果如圖4-23和圖4-24所示。其中,圖4-23所示為用戶實際收到的短信內(nèi)容,圖4-24所示為App監(jiān)視短信并解析完成的流量數(shù)據(jù)頁面。

圖4-23 用戶收到的短信內(nèi)容

圖4-24 內(nèi)容觀察器監(jiān)視并解析得到的流量信息
總結(jié)一下在Content組件經(jīng)常使用的系統(tǒng)URI,詳細的URI取值說明見表4-3。
表4-3 常用的系統(tǒng)URI取值說明

- 元器件易學(xué)通:常用器件分冊
- 5G通信系統(tǒng)定位技術(shù)原理與方法
- App Inventor移動應(yīng)用開發(fā)標準教程
- 電子工程師自學(xué)速成:入門篇(第2版)
- 通信專業(yè)實務(wù):動力與環(huán)境
- Photoshop移動UI界面設(shè)計實用教程
- PLC控制技術(shù)(西門子S7-200)
- 寬帶無線通信多址傳輸技術(shù)演進
- 電磁場與電磁波
- 電子裝配工技能實訓(xùn)與考核指導(dǎo)(中、高級工)
- PTN分組傳送設(shè)備組網(wǎng)與實訓(xùn)(第2版)
- 混沌保密通信理論及其在電視制導(dǎo)系統(tǒng)中的應(yīng)用
- Photoshop手機App界面設(shè)計實戰(zhàn)入門
- 移動終端安全關(guān)鍵技術(shù)與應(yīng)用分析
- 數(shù)字身份:在數(shù)字空間,如何安全地證明你是你