(1)ContentProvider是什么?
ContentProvider,簡稱CP。
做App開發的同學,尤其是電商類App,對CP并不熟悉,對這個概念的最大程度的了解,也僅僅是建立在書本上,它是Android四大組件中的一個。
做系統管理類的App,比如說手機助手這種,有機會頻繁使用CP。
而對于應用類App,數據通常存在服務器端,其它應用類App也想使用的時候,一般都是從服務器取數據,所以沒機會使用到CP。
有時候我們會在自己的App中讀取通信錄或者短信的數據,這時候就需要用到CP了。通信錄或者短信的數據,是以CP的形式提供的,我們在App這邊,是使用方。
對于做應用類App的同學,很少有機會自定義CP供其它App使用。
我們快速回顧一下在App中怎么使用CP。

1)定義CP的App1:
在App1中定義一個CP的子類MyContentProvider,并在Manifest中聲明,為此要在MyContentProvider中實現CP的增刪改查四個方法:


2)使用CP的App2:
在App2訪問App1中定義的CP,為此,要使用到ContentResolver,它也提供了增刪改查4個方法,用于訪問App1中定義的CP:

首先我們看一下ContentResolver的增刪改查這4個方法的底層實現,其實都是和AMS通信,最終調用App1的CP的增刪改查4個方法,后面我們會講到這個流程是怎么樣的。
其次,URI是CP的身份證,唯一標識。
我們在App1中為CP聲明URI,也就是authorities的值為baobao,那么在App2中想使用它,就在ContentResolver的增刪改查4個方法中指定URI,格式為:
~~~
uri = Uri.parse("content://baobao/");
~~~
接下來把兩個App都進入debug模式,就可以從App2調試進入App1了,比如說,query操作。
(2)CP的本質
CP的本質是把數據存儲在SQLite數據庫中。
各種數據源,有各種格式,比如短信、通信錄,它們在SQLite中就是不同的數據表,但是對外界的使用者而言,就需要封裝成統一的訪問方式,比如說對于數據集合而言,必須要提供增刪改查四個方法,于是我們在SQLite之上封裝了一層,也就是CP。
(3)匿名共享內存(ASM)
CP讀取數據使用到了匿名共享內存,英文簡稱ASM,所以你看上面CP和AMS通信忙的不亦樂乎,其實下面別有一番風景。
關于ASM的概念,它其實也是個Binder通信,我畫個圖哦,你們就明白了:

什么?還沒看懂?那我再畫一個類的交互關系圖:

這里的CursorWindow就是匿名共享內存。
這個流程,簡單來說是這樣的:
* 1)Client內部有一個CursorWindow對象,發送請求的時候,把這個CursorWindow類型的對象傳過去,這個對象暫時為空。
* 2)Server收到請求,搜集數據,填充到這個CursorWindow對象。
* 3)Client讀取內部的這個CursorWindow對象,獲取到數據。
由此可見,這個CursorWindow對象,就是匿名共享內存,這是同一塊匿名內存。
舉個生活中的例子就是,你定牛奶,在你家門口放個箱子,送牛奶的人每天早上往這個箱子放一袋牛奶,你睡醒了去箱子里取牛奶。這個牛奶箱就是匿名共享內存。
(4)CP與AMS的通信流程
接下來我們看一下CP是怎么和AMS通信的。
能堅持看到這里的人,都不容易。我努力多貼圖,不貼代碼,即使有代碼,也是App開發人員能看懂的代碼。
還是拿App2想訪問App1中定義的CP為例子。我們就看CP的insert方法。

上面這5行代碼,包括了啟動CP和執行CP方法兩部分,分水嶺在insert方法,insert方法的實現,前半部分仍然是在啟動CP,當CP啟動后獲取到CP的代理對象,后半部分是通過代理對象,調用insert方法。
整體的流程如下圖所示:

* 1)App2發送消息給AMS,想要訪問App1中的CP。
* 2)AMS檢查發現,App1中的CP沒啟動過,為此新開一個進程,啟動App1,然后獲取到App1啟動的CP,把CP的代理對象返回給App2。
* 3)App2拿到CP的代理對象,也就是IContentProvider,就調用它的增刪改查4個方法了,接下來就是使用ASM來傳輸數據或者修改數據了,也就是上面提到的CursorWindow這個類,取得數據或者操作結果即可,作為App的開發人員,不需要知道太多底層的詳細信息,用不上。
至此,關于CP的介紹就結束了。下一篇文章,我們看一下App的安裝流程,也就PMS。
**附錄**:
ContentProvider的完整啟動過程圖

ContentProvider的完整數據更新通知過程圖

ContentProvider的完整數據共享過程圖

- 前言
- Android 熱補丁技術——資源的熱修復
- 插件化系列詳解
- Dex分包——MultiDex
- Google官網——配置方法數超過 64K 的應用
- IMOOC熱修復與插件化筆記
- 第1章 class文件與dex文件解析
- Class文件解析
- dex文件解析
- class與dex對比
- 第2章 虛擬機深入講解
- 第3章 ClassLoader原理講解
- 類的加載過程
- ClassLoade源碼分析
- Android中的動態加載
- 第4章 熱修復簡單講解
- 第5章 熱修復AndFix詳解
- 第6章 熱修復Tinker詳解及兩種方式接入
- 第7章 引入熱修復后代碼及版本管理
- 第8章 插件化原理深入講解
- 第9章 使用Small完成插件化
- 第10章 使用Atlas完成插件化
- 第11章 課程整體總結
- DN學院熱修復插件化筆錄
- 插件化
- 熱修復
- Android APP開發應掌握的底層知識
- 概述
- Binder
- AIDL
- AMS
- Activity的啟動和通信原理
- App啟動流程第2篇
- App內部的頁面跳轉
- Context家族史
- Service
- BroadcastReceiver
- ContentProvider
- PMS及App安裝過程