該文總結下工作當中維護的聯系人子產品中的資料查詢流程。該流程在很多系統APP上都類似,了解這個過程還是很有必要的。
在Android應用架構中一般都會劃分為三層:資料層、資料通路層和業務層。資料層基本都是用sqlite來存儲資料,資料通路層是借用四大元件中的内容提供器來實作,業務層就是各個應用,比如電話本。三層結構如下圖所示:

這裡将詳細總結下電話本對資料庫的查詢流程。
1、建立資料庫
當系統啟動,所有服務都準備好之後,ContactsUpgradeReceiver類将接受到重新開機廣播,在廣播接受類中會去擷取聯系人資料的執行個體,在擷取執行個體當中會去建立資料庫和表,如下圖所示:
2、内容提供器的建立
聯系人當中用到最多的資料通路接口都是在ContactsProvider2中建立的。它提供了一些增删改查的接口,這些接口其實就是借用前面建立的資料庫進行操作。
3、業務層資料查詢流程
當資料層和資料通路層都準備好之後,業務層才可以調用接口。下面給出一個聯系人主界面查詢資料的大緻流程。
聯系人的主界面一般會分為幾個碎片,每個碎片代表一個界面,在碎片的父類當中會實作資料的異步查詢。
舉例:DefaultContactBrowseListFragment
它的父類ContactEntryListFragment封裝了大部分的工作。包括建立擴充卡、加載頁面、建立查詢加載器和查詢結束。
子類一般會根據業務的需求來進行各種定制。它的工作有建立擴充卡、加載頁面、建立查詢加載器。其實就是對父類實作類的覆寫。在擴充卡中還會對查詢加載器進行查詢配置。擴充卡也有跟碎片一樣的實作模式,大部分操作都在父類DefaultContactListAdapter中實作,使用者也可以繼承它來進行各種查詢定制。比如聯系人對SIM卡的過濾、對沒有分組成員的過濾等等。具體的流程圖如下所示:
查詢完會傳回一個Cursor對象,擴充卡會用這個對象進行資料和頁面控件的綁定。
在業務層中會根據loader機制,最後會調用内容提供器注冊的uri,進行異步查詢,如下:
final Cursor cursor = getActivity().getContentResolver().query(Contacts.CONTENT_URI,
LOOKUP_PROJECTION, Contacts.IN_VISIBLE_GROUP + "!=0", null, null);
接着會根據binder機制走到ContactsProvider2中的查詢接口進行查詢。在queryLocal方法中會比對不同的uri進行表的映射和查詢配置。