原文出處——>[Android應用程序組件Content Provider簡要介紹和學習計劃](http://blog.csdn.net/luoshengyang/article/details/6946067)
在Android系統中,Content Provider作為應用程序四大組件之一,它起到在應用程序之間共享數據的作用,同時,它還是標準的數據訪問接口。前面的一系列文章已經分析過Android應用程序的其它三大組件(Activity、Service和Broadcast Receiver)了,本文將簡要介紹Content Provider組件在Android應用程序設計中的地位,為進一步學習打好基礎。
我們知道,在Android系統上,每一個應用程序都有一個獨立的用戶ID。為什么要給每一個應用程序分配一個獨立的用戶ID呢?這是為了保護各個應用程序的數據不被其它應用程序惡意破壞而設計的。Android系統是基于Linux內核來開發的,而在Linux系統中,每一個文件除了文件本身的數據之外,還具有一定的屬性,其中最重要的就是文件權限了。所謂的文件權限,就是指對文件的讀、寫和執行權限。此外,Linux還是一個多用戶的操作系統,因此,Linux將系統中的每一個文件都與一個用戶以及用戶組關聯起來,基于不同的用戶而賦予不同的文件權限。只有當一個用戶對某個文件擁有相應的權限時,才能執行相應的操作,例如,只有當一個用戶對某個文件擁有讀權限時,這個用戶才可以調用read系統調用來讀取這個文件的內容。Android系統繼承了Linux系統管理文件的方法,為每一個應用程序分配一個獨立的用戶ID和用戶組ID,而由這個應用程序創建出來的數據文件就賦予相應的用戶以及用戶組讀寫的權限,其余用戶則無權對該文件進行讀寫。
如果我們通過adb shell命令連上模擬器,切換到/data/data目錄下,就可以看到很多以應用程序包(package)命名的文件夾,這些文件夾里面存放的就是各個應用程序的數據文件,例如,如果我們進入到Android系統日歷應用程序數據目錄com.android.providers.calendar下的databases文件中,會看到一個用來保存日歷數據的數據庫文件calendar.db,它的權限設置如下所示:
~~~
root@android:/data/data/com.android.providers.calendar/databases # ls -l
-rw-rw---- app_17 app_17 33792 2011-11-07 15:50 calendar.db
~~~
在前面的十字符-rw-rw----中,最前面的符號-表示這是一個普通文件,接下來的三個字符rw-表示這個文件的所有者對這個文件可讀可寫不可執行,再接下來的三個字符rw-表示這個文件的所有者所在的用戶組的用戶對這個文件可讀可寫不可執行,而最后的三個字符---表示其它的用戶對這個文件不可讀寫也不可執行,因為這是一個數據文件,所認所有用戶都不可以執行它是正確的。在接下來的兩個app_17字符串表示這個文件的所有者和這個所有者所在的用戶組的名稱均為app_17,這是應用程序在安裝的時候系統分配的,在不同的系統上,這個字符串可能是不一樣,不過它所表示的意義是一樣的。這意味著只有用戶ID為app_17或者用戶組ID為app_17的那些進程才可以對這個calendar.db文件進行讀寫操作。我們通過執行終端上執行ps命令來查看一下哪個進程的用戶ID為app_17:
~~~
root@android:/ # ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 272 184 c009f230 0000875c S /init
... ... ... ... ... ... ... ...
app_17 295 35 107468 21492 ffffffff afd0c38c S com.android.providers.calendar
.. ... ... ... ... ... ... ...
root 556 527 892 332 00000000 afd0b24c R ps
~~~
這里我們看到,正是這個日歷應用程序com.android.providers.calendar進程的用戶ID為app_17。這樣,就驗證了我們前面的分析了:只有這個日歷應用程序com.android.providers.calendar才可以對這個calendar.db文件進行讀寫操作。這個日歷應用程序com.android.providers.calendar其實是由一個Content Provider組件來實現的,在下一篇文章中,我們將實現一個自己的Content Provider,然后再對Content Provider的實現原理進行詳細分析。
Android系統對應用程序的數據文件作如此嚴格的保護會不會有點過頭了呢?如果一個應用程序想要讀寫另外一個應用程序的數據文件時,應該怎么辦呢?舉一個典型的應用場景,我們在開發自己的應用程序時,有時候會希望讀取通訊錄里面某個聯系人的手機號碼或者電子郵件,以便可以對這個聯系人打電話或者發送電子郵件,這時候就需要讀取通訊錄里面的聯系人數據文件了。
現在在互聯網里面,都流行平臺的概念,各大公司都打著開放平臺的口號,來吸引第三方來為自己的平臺做應用,例如,國外最流行的Fackbook開放平臺和Google+開放平臺等,國內的有騰訊的Q+開放平臺,還有新浪微博開放平臺、360的開放平臺等。這些開放平臺的核心就是要開放用戶數據給第三方來使使用,就像前面我們說的Android系統的通訊錄,它需要把自己聯系人數據開放出來給其它應用程序使用。但是,這些數據都是各個平臺自己的核心數據和核心競爭力,它們需要有保護地進行開放。Android系統中的Content Provider應用程序組件正是結合上面分析的這種文件權限機制來秉承這種有保護地開放自己的數據給其它應用程序使用的理念。
從另外一個觀點來看,即使我們不是在做平臺,而只是在做一個應用程序軟件,是不是就不需要這么使用到Content Provider機制了呢?非也,現在的應用程序軟件,越著公司業務的成長,越來越龐大,越來越復雜。軟件工程告訴我們,我們在設計這種大型的復雜的軟件的時候,需要分模塊和分層次來實現各個子功能組件,使得各個模塊功能以松耦合的方式組織在一起完成整個應用程序功能。這樣做的好處當然就是便于我們維護和擴展應用程序的代碼和功能了,以及適應復雜的業務環境。在一個大型的應用程序軟件架構中,從垂直的方向來看,一般都會劃分為數據層、數據訪問接口層以及上面的業務層。數據層用來保存數據,這些數據可以用文件的方式來組織,也可以用數據庫的方式來組織,甚至可以保存在網絡中;數據訪問層負責向上面的業務層提供數據,而向下管理好數據層的數據;最后業務層通過數據訪問層來獲取一些業務相關的數據來實現自己的業務邏輯。
基于這種開放平臺建設或者復雜軟件架構的理念,我們得出一個Android應用程序設計的一般方法,如下圖所示:

在這個架構中, 數據層采用數據庫、文件或者網絡來保存數據,數據訪問層使用Content Provider來實現,而業務層就通過一些APP來實現。為了降低各個功能模塊間耦合性,我們可以把業務層的各個APP和數據訪問層中的Content Provider,放在不同的應用程序進程中來實現,而數據庫中的數據統一由Content Provider來管理,即Content Provider擁有對這些文件直接進行讀寫的權限,同時,它又根據需要來有保護地把這些數據開放出來給上層的APP來使用。
那么,Content Provider又是如何把數據開放給上面的APP使用呢?一方面是這些APP沒有權限讀取這些數據文件,另一外面是Content Provider和這些APP是在不同的進程空間里面。回憶一下,我們在前面Android進程間通信(IPC)機制Binder簡要介紹和學習計劃這一系文章中學習的Android系統中Binder進程間通信機制,不同的應用程序之間可以通過Binder進程間調用來傳輸數據。因此,前面關于一個應用程序應該如何來讀寫另外一個應用程序的數據的問題的答案就是使用Binder進程間通信機制,雖然一個應用程序不能直接讀取另一個應用程序的數據,但是它卻可以通過進程間通信方式來請求另一個這個應用程序給它傳輸數據。這樣我們就解決了文件權限限制所帶來的問題了。
然而,事情還不是那么簡單,一般Content Provider管理的都是大量的數據,如果在進程間傳輸大量的數據,效率是不是會很低下呢?這時候,前面我們在Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃這一系列文章中學習的匿名共享內存(Anonymous Shared Memory)就派上用場了。把需要在進程間傳輸的數據都寫到共享內存中去,然后只能通過Binder進程間通信機制來傳輸一個共享內存的打開文件描述符給對方就好了,是不是很簡單呢。在Android系統中,Binder進程間通信機制和匿名共享內存機制結合在一起使用,真是太完美了。
Content Provider如何在應用程序之間共享數據以及它在應用程序設計中的地位就簡要介紹到這里了,在接下來的四篇文章中,我們將以一個 Content Provider的應用實例來詳細分析它的啟動過程、數據共享原理以及數據監控機制:
1. Android應用程序組件Content Provider的應用實例。
2. Android應用程序組件Content Provider的啟動過程源代碼分析。
3. Android應用程序組件Content Provider在不同應用程序之間共享數據的原理分析。
4. Android應用程序組件Content Provider的數據監控機制分析。
- 前言
- Android組件設計思想
- Android源代碼開發和調試環境搭建
- Android源代碼下載和編譯
- Android源代碼情景分析法
- Android源代碼調試分析法
- 手把手教你為手機編譯ROM
- 在Ubuntu上下載、編譯和安裝Android最新源代碼
- 在Ubuntu上下載、編譯和安裝Android最新內核源代碼(Linux Kernel)
- 如何單獨編譯Android源代碼中的模塊
- 在Ubuntu上為Android系統編寫Linux內核驅動程序
- 在Ubuntu上為Android系統內置C可執行程序測試Linux內核驅動程序
- 在Ubuntu上為Android增加硬件抽象層(HAL)模塊訪問Linux內核驅動程序
- 在Ubuntu為Android硬件抽象層(HAL)模塊編寫JNI方法提供Java訪問硬件服務接口
- 在Ubuntu上為Android系統的Application Frameworks層增加硬件訪問服務
- 在Ubuntu上為Android系統內置Java應用程序測試Application Frameworks層的硬件服務
- Android源代碼倉庫及其管理工具Repo分析
- Android編譯系統簡要介紹和學習計劃
- Android編譯系統環境初始化過程分析
- Android源代碼編譯命令m/mm/mmm/make分析
- Android系統鏡像文件的打包過程分析
- 從CM刷機過程和原理分析Android系統結構
- Android系統架構概述
- Android系統整體架構
- android專用驅動
- Android硬件抽象層HAL
- Android應用程序組件
- Android應用程序框架
- Android用戶界面架構
- Android虛擬機之Dalvik虛擬機
- Android硬件抽象層
- Android硬件抽象層(HAL)概要介紹和學習計劃
- Android專用驅動
- Android Logger驅動系統
- Android日志系統驅動程序Logger源代碼分析
- Android應用程序框架層和系統運行庫層日志系統源代碼分析
- Android日志系統Logcat源代碼簡要分析
- Android Binder驅動系統
- Android進程間通信(IPC)機制Binder簡要介紹和學習計劃
- 淺談Service Manager成為Android進程間通信(IPC)機制Binder守護進程之路
- 淺談Android系統進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路
- Android系統進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析
- Android系統進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析
- Android系統進程間通信Binder機制在應用程序框架層的Java接口源代碼分析
- Android Ashmem驅動系統
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)驅動程序源代碼分析
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)在進程間共享的原理分析
- Android系統匿名共享內存(Anonymous Shared Memory)C++調用接口分析
- Android應用程序進程管理
- Android應用程序進程啟動過程的源代碼分析
- Android系統進程Zygote啟動過程的源代碼分析
- Android系統默認Home應用程序(Launcher)的啟動過程源代碼分析
- Android應用程序消息機制
- Android應用程序消息處理機制(Looper、Handler)分析
- Android應用程序線程消息循環模型分析
- Android應用程序輸入事件分發和處理機制
- Android應用程序鍵盤(Keyboard)消息處理機制分析
- Android應用程序UI架構
- Android系統的開機畫面顯示過程分析
- Android幀緩沖區(Frame Buffer)硬件抽象層(HAL)模塊Gralloc的實現原理分析
- SurfaceFlinger
- Android系統Surface機制的SurfaceFlinger服務
- SurfaceFlinger服務簡要介紹和學習計劃
- 啟動過程分析
- 對幀緩沖區(Frame Buffer)的管理分析
- 線程模型分析
- 渲染應用程序UI的過程分析
- Android應用程序與SurfaceFlinger服務的關系
- 概述和學習計劃
- 連接過程分析
- 共享UI元數據(SharedClient)的創建過程分析
- 創建Surface的過程分析
- 渲染Surface的過程分析
- Android應用程序窗口(Activity)
- 實現框架簡要介紹和學習計劃
- 運行上下文環境(Context)的創建過程分析
- 窗口對象(Window)的創建過程分析
- 視圖對象(View)的創建過程分析
- 與WindowManagerService服務的連接過程分析
- 繪圖表面(Surface)的創建過程分析
- 測量(Measure)、布局(Layout)和繪制(Draw)過程分析
- WindowManagerService
- WindowManagerService的簡要介紹和學習計劃
- 計算Activity窗口大小的過程分析
- 對窗口的組織方式分析
- 對輸入法窗口(Input Method Window)的管理分析
- 對壁紙窗口(Wallpaper Window)的管理分析
- 計算窗口Z軸位置的過程分析
- 顯示Activity組件的啟動窗口(Starting Window)的過程分析
- 切換Activity窗口(App Transition)的過程分析
- 顯示窗口動畫的原理分析
- Android控件TextView的實現原理分析
- Android視圖SurfaceView的實現原理分析
- Android應用程序UI硬件加速渲染
- 簡要介紹和學習計劃
- 環境初始化過程分析
- 預加載資源地圖集服務(Asset Atlas Service)分析
- Display List構建過程分析
- Display List渲染過程分析
- 動畫執行過程分析
- Android應用程序資源管理框架
- Android資源管理框架(Asset Manager)
- Asset Manager 簡要介紹和學習計劃
- 編譯和打包過程分析
- Asset Manager的創建過程分析
- 查找過程分析
- Dalvik虛擬機和ART虛擬機
- Dalvik虛擬機
- Dalvik虛擬機簡要介紹和學習計劃
- Dalvik虛擬機的啟動過程分析
- Dalvik虛擬機的運行過程分析
- Dalvik虛擬機JNI方法的注冊過程分析
- Dalvik虛擬機進程和線程的創建過程分析
- Dalvik虛擬機垃圾收集機制簡要介紹和學習計劃
- Dalvik虛擬機Java堆創建過程分析
- Dalvik虛擬機為新創建對象分配內存的過程分析
- Dalvik虛擬機垃圾收集(GC)過程分析
- ART虛擬機
- Android ART運行時無縫替換Dalvik虛擬機的過程分析
- Android運行時ART簡要介紹和學習計劃
- Android運行時ART加載OAT文件的過程分析
- Android運行時ART加載類和方法的過程分析
- Android運行時ART執行類方法的過程分析
- ART運行時垃圾收集機制簡要介紹和學習計劃
- ART運行時Java堆創建過程分析
- ART運行時為新創建對象分配內存的過程分析
- ART運行時垃圾收集(GC)過程分析
- ART運行時Compacting GC簡要介紹和學習計劃
- ART運行時Compacting GC堆創建過程分析
- ART運行時Compacting GC為新創建對象分配內存的過程分析
- ART運行時Semi-Space(SS)和Generational Semi-Space(GSS)GC執行過程分析
- ART運行時Mark-Compact( MC)GC執行過程分析
- ART運行時Foreground GC和Background GC切換過程分析
- Android安全機制
- SEAndroid安全機制簡要介紹和學習計劃
- SEAndroid安全機制框架分析
- SEAndroid安全機制中的文件安全上下文關聯分析
- SEAndroid安全機制中的進程安全上下文關聯分析
- SEAndroid安全機制對Android屬性訪問的保護分析
- SEAndroid安全機制對Binder IPC的保護分析
- 從NDK在非Root手機上的調試原理探討Android的安全機制
- APK防反編譯
- Android視頻硬解穩定性問題探討和處理
- Android系統的智能指針(輕量級指針、強指針和弱指針)的實現原理分析
- Android應用程序安裝過程源代碼分析
- Android應用程序啟動過程源代碼分析
- 四大組件源代碼分析
- Activity
- Android應用程序的Activity啟動過程簡要介紹和學習計劃
- Android應用程序內部啟動Activity過程(startActivity)的源代碼分析
- 解開Android應用程序組件Activity的"singleTask"之謎
- Android應用程序在新的進程中啟動新的Activity的方法和過程分析
- Service
- Android應用程序綁定服務(bindService)的過程源代碼分析
- ContentProvider
- Android應用程序組件Content Provider簡要介紹和學習計劃
- Android應用程序組件Content Provider應用實例
- Android應用程序組件Content Provider的啟動過程源代碼分析
- Android應用程序組件Content Provider在應用程序之間共享數據的原理分析
- Android應用程序組件Content Provider的共享數據更新通知機制分析
- BroadcastReceiver
- Android系統中的廣播(Broadcast)機制簡要介紹和學習計劃
- Android應用程序注冊廣播接收器(registerReceiver)的過程分析
- Android應用程序發送廣播(sendBroadcast)的過程分析