原文出處——>[Android應用程序與SurfaceFlinger服務之間的共享UI元數據(SharedClient)的創建過程分析](http://blog.csdn.net/luoshengyang/article/details/7867340)
在前面一篇文章中,我們分析了Android應用程序與SurfaceFlinger服務的連接過程。Android應用程序成功連接上SurfaceFlinger服務之后,還需要一塊匿名共享內存來和SurfaceFlinger服務共享它的UI元數據,以便使得SurfaceFlinger服務可以正確地為它創建以及渲染Surface。在本文中,我們將詳細地分析這塊用來保存UI元數據的匿名共享內存的創建過程。
在Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一文中提到,用來保存Android應用程序的UI元數據的匿名共享內存最終是被結構化為一個SharedClient對象來訪問的。每一個與UI有關的Android應用程序進程有且僅有一個SharedClient對象,而且這些SharedClient對象是由Android應用程序請求SurfaceFlinger服務創建的:Android應用程序首先獲得SurfaceFlinger服務的一個Binder代理接口,然后再通過這個代理接口得到另外一個類型為UserClient的Binder代理接口,最后就可以通過后一個Binder代理接口來獲得一個SharedClient對象。
由于每一個與UI有關的Android應用程序進程有且僅有一個SharedClient對象,因此,Android系統就通過一個單例模式的類來專負責創建和管理這個SharedClient對象。這個類的名稱為SurfaceClient,定義在frameworks/base/libs/surfaceflinger_client/Surface.cpp文件中,如下所示:
~~~
class SurfaceClient : public Singleton<SurfaceClient>
{
// all these attributes are constants
sp<ISurfaceComposer> mComposerService;
sp<ISurfaceComposerClient> mClient;
status_t mStatus;
SharedClient* mControl;
sp<IMemoryHeap> mControlMemory;
SurfaceClient()
: Singleton<SurfaceClient>(), mStatus(NO_INIT)
{
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
mComposerService = sf;
mClient = sf->createClientConnection();
if (mClient != NULL) {
mControlMemory = mClient->getControlBlock();
if (mControlMemory != NULL) {
mControl = static_cast<SharedClient *>(
mControlMemory->getBase());
if (mControl) {
mStatus = NO_ERROR;
}
}
}
}
friend class Singleton<SurfaceClient>;
public:
status_t initCheck() const {
return mStatus;
}
SharedClient* getSharedClient() const {
return mControl;
}
ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
// TODO: we could cache a few tokens here to avoid an IPC
return mClient->getTokenForSurface(sur);
}
void signalServer() const {
mComposerService->signal();
}
};
~~~
當SurfaceClient類的靜態成員函數getInstance第一次被調用的時候,系統就會在對應的應用程序進程中創建一個SurfaceClient對象,即會調用SurfaceClient類的構造函數。SurfaceClient類的構造函數首先會調用ComposerService類的靜態成員函數getComposerService來獲得一個SurfaceFlinger服務的代理接口,并且保存在SurfaceClient類的成員變量mComposerService中,以便以后可以使用。ComposerService類的靜態成員函數getComposerService在前面Android應用程序與SurfaceFlinger服務的連接過程分析一文中已經分析過了,這里不再詳述。有了SurfaceFlinger服務的代理接口sf之后,SurfaceClient類的構造函數接著就可以調用它的成員函數createClientConnection來獲得一個類型為UserClient的Binder代理接口,這個Binder代理接口實現了ISurfaceComposerClient接口,因此,我們可以將它保存在SurfaceClient類的成員變量mClient中。最后,SurfaceClient類的構造函數就調用前面獲得的類型為ISurfaceComposerClient的Binder代理接口mClient的成員函數getControlBlock來獲得一塊用來描述應用程序UI元數據的匿名共享內存mControlMemory ,并且將這些匿名共享內存強制轉化為一個SharedClient對象mControl,以便后面可以方便地訪問UI元數據。
以上就是Android應用程序與SurfaceFlinger服務之間的共享UI元數據(SharedClient)的創建過程的總體描述,接下來我們再詳細分析每一步的實現。現在,我們繼續分析一下SurfaceClient類的其余成員函數的實現:
1. 成員函數initCheck用來檢查一個Android應用程序進程是否已經成功地請求SurfaceFlinger服務創建了一塊用來描述UI元數據的SharedClient對象了。
2. 成員函數getSharedClient用來返回用來描述UI元數據的SharedClient對象mControl。
3. 成員函數getTokenForSurface用來返回由參數sur所描述的一個Surface的Token值。這個Token值由SurfaceFlinger服務來創建和管理,并且可以通過前面所獲得的類型為UserClient的Binder代理接口mClient的成員函數getTokenSurface來獲得。
4. 成員函數signalServer用來通知SurfaceFlinger服務更新Android應用程序UI,這是通過調用SurfaceFlinger服務的代理接口mComposerService的成員函數signal來實現的,實際上就是向SurfaceFlinger服務發送一個信號,以便可以將它喚醒起來更新UI。
介紹完成SurfaceClient類的實現之后,我們還需要了解一下兩個類的實現,即UserClient類和SharedClient類的實現,以便可以幫助我們了解用來保存Android應用程序的UI元數據的匿名共享內存的創建過程,以及幫助后面兩篇文章對Surface的創建和渲染過程的分析。
接下來,我們就首先分析UserClient類的實現,接著再分析SharedClient類的實現。
在Android應用程序與SurfaceFlinger服務的連接過程分析一文的圖2中,我們介紹了用來連接Android應用程序和SurfaceFlinger服務的Client類,而UserClient類和Client類是類似的,它們都實現了相同的接口,只不過是側重點有所不同。Android應用程序與SurfaceFlinger服務的連接過程分析一文的圖2中的Client類替換成UserClient類,就可以得到UserClient類的實現結構圖,如圖1所示:

圖1 UserClient類的實現結構圖
UserClient類與Client類最重要的區別是,前者實現了ISurfaceComposerClient接口的成員函數getControlBlock,而后者實現了ISurfaceComposerClient接口的成員函數createSurface。后面我們就會分析UserClient類是如何實現ISurfaceComposerClient接口的成員函數getControlBlock的。
UserClient類的實現暫時就介紹到這里,接下來我們來看SharedClient類的實現。為了方便描述,我們把Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一文的圖4和圖5貼出來,如以下圖2和圖3所示:

圖2 用來描述Android應用程序的UI元數據的SharedClient

圖3 SharedBufferStack的結構示意圖
每一個SharedClient對象包含了至多31個SharedBufferStack,而每一個SharedBufferStack都對應一個Android應用程序進程中的一個Surface。
SharedClient類定義在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h 文件中,如下所示:
~~~
class SharedClient
{
public:
SharedClient();
~SharedClient();
......
private:
......
SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
};
~~~
它有一個大小為SharedBufferStack::NUM_LAYERS_MAX的SharedBufferStack數組。SharedBufferStack::NUM_LAYERS_MAX的值等于31,定義在SharedBufferStack類中。
SharedBufferStack類同樣是定義在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h 文件中,如下所示:
~~~
class SharedBufferStack
{
......
public:
// When changing these values, the COMPILE_TIME_ASSERT at the end of this
// file need to be updated.
static const unsigned int NUM_LAYERS_MAX = 31;
static const unsigned int NUM_BUFFER_MAX = 16;
static const unsigned int NUM_BUFFER_MIN = 2;
static const unsigned int NUM_DISPLAY_MAX = 4;
......
struct SmallRect {
uint16_t l, t, r, b;
};
struct FlatRegion {
static const unsigned int NUM_RECT_MAX = 5;
uint32_t count;
SmallRect rects[NUM_RECT_MAX];
};
struct BufferData {
FlatRegion dirtyRegion;
SmallRect crop;
uint8_t transform;
uint8_t reserved[3];
};
SharedBufferStack();
......
status_t setDirtyRegion(int buffer, const Region& reg);
status_t setCrop(int buffer, const Rect& reg);
status_t setTransform(int buffer, uint8_t transform);
Region getDirtyRegion(int buffer) const;
Rect getCrop(int buffer) const;
uint32_t getTransform(int buffer) const;
// these attributes are part of the conditions/updates
volatile int32_t head; // server's current front buffer
volatile int32_t available; // number of dequeue-able buffers
volatile int32_t queued; // number of buffers waiting for post
......
// not part of the conditions
......
volatile int8_t index[NUM_BUFFER_MAX];
......
int8_t headBuf; // last retired buffer
......
BufferData buffers[NUM_BUFFER_MAX];
};
~~~
下面我們簡要地對SharedBufferStack類進行分析。
首先,SharedBufferStack類在內部定義了四個常量:
* NUM_LAYERS_MAX -- 表示一個Android應用程序最多可以有NUM_LAYERS_MAX個Layer,可以將一個Layer理解為一個Surface。
* NUM_BUFFER_MAX -- 表示一個SharedBufferStack至多可以有NUM_BUFFER_MAX個UI元數據緩沖區。
* NUM_BUFFER_MIN -- 表示一個SharedBufferStack至少要有UM_BUFFER_MIN個UI元數據緩沖區。
* NUM_DISPLAY_MAX -- 表示Android系統至多可以支持NUM_DISPLAY_MAX個顯示屏。
從這些常量就可以看出:
1. Android系統至多支持4個顯示屏。
2. 一個Android應用程序至多可以同時創建31個Surface。
3. 一個Surface可以有2~16個UI元數據緩沖區,即可以使用2~16緩沖區技術來渲染Surface。
其次,SharedBufferStack類在內部定義了三個結構體:
* SmallRect -- 用來描述一個矩形區域,其中,成員變量l、t,、r和b分別表示左上和右下兩個角的位置。
* FlatRegion -- 用來描述一個SmallRect數組rects ,數組的大小為NUM_RECT_MAX,但是實際個數為count。
* BufferData -- 用來描述一個UI元數據緩沖區,它有四個成員變量dirtyRegion、crop、transform和reserved,其中,dirtyRegion用來描述一個Surface需要更新的區域,即裁剪區域,crop用來描述一個Surface的紋理坐標,transform用來描述一個Surface的旋轉方向,例如,旋轉90度或者上下翻轉等等,而reserved是保留給以后使用的。通過這個UI元數據緩沖區,SurfaceFlinger服務就可以正確地把一個Surface的圖形緩沖區所描述的圖形渲染到屏幕來。
SharedBufferStack類有一個BufferData數組buffers,它的大小為NUM_BUFFER_MAX,即16,就是用來一組UI元數據緩沖區的,這些UI元數據緩沖區的內容可以分別通過setDirtyRegion、setCrop、setTransform、getDirtyRegion、getCrop和getTransform這六個成員函數來訪問。這六個成員函數的第一個參數均為一個int值,用來描述要訪問的是哪一個BufferData的數據。
SharedBufferStack類還有另外一個類型為int8_t的數組index,它的大小也為NUM_BUFFER_MAX。這個index數組才是一個真正的Stack,它按照一定的規則來訪問。index數組的每一個元素的值均是一個索引值,用來映射到數組buffers中去的。例如,假設index[0]的值等于2,那么它就對應數組buffers中的第2個元素,即buffers[2]。
SharedBufferStack類的其余重要成員變量的含義如下所示:
* head -- 用來描述一個SharedBufferStack的頭部,它是一個索引值,是映射到數組index中去的。
* available -- 用來描述一個SharedBufferStack中的空閑UI元數據緩沖區的個數。
* queued -- 用來描述一個SharedBufferStack中的已經補使用了的UI元數據緩沖區的個數,即那些在排隊等待SurfaceFlinger服務使用的UI元數據緩沖區。
* headBuf -- 用來描述一個SharedBufferStack的頭部所對應的UI元數據緩沖區的編號,這個編號是映射到數組buffers中去。
關于SharedBufferStack類的實現,我們就暫時介紹到這里,在下一篇文章分析Android應用程序的Surface創建過程時,我們再通過SharedBufferServer類和SharedBufferClient類的實現來進一步理解SharedBufferStack類的實現。
現在,我們就開始詳細分析Android應用程序與SurfaceFlinger服務之間的共享UI元數據的創建過程,如圖4所示:

圖 4 Android應用程序的共享UI元數據的創建過程
接下來我們就詳細分析每一個步驟。
Step 1. SurfaceFlinger::createClientConnection
~~~
sp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
{
sp<ISurfaceComposerClient> bclient;
sp<UserClient> client(new UserClient(this));
status_t err = client->initCheck();
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}
~~~
SurfaceFlinger類的成員函數createClientConnection實現在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,它的實現很簡單,只是創建了一個類型為UserClient的Binder對象client,并且獲得它的一個ISurfaceComposerClient接口,最后將這個ISurfaceComposerClient接口,即一個UserClient代理對象,返回給Android應用程序進程。
接下來,我們再繼續分析UserClient對象的創建過程,,即UserClient類的構造函數的實現。
Step 2. new UserClient
~~~
UserClient::UserClient(const sp<SurfaceFlinger>& flinger)
: ctrlblk(0), mBitmap(0), mFlinger(flinger)
{
const int pgsize = getpagesize();
const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
mCblkHeap = new MemoryHeapBase(cblksize, 0,
"SurfaceFlinger Client control-block");
ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
if (ctrlblk) { // construct the shared structure in-place.
new(ctrlblk) SharedClient;
}
}
~~~
UserClient類的成員變量mFlinger是一個類型為SurfaceFlinger的強指針,它指向了SurfaceFlinger服務, UserClient類的另外一個成員變量mBitmap是一個int32_t值,它是用來為Android應用程序的Surface分配Token值的,即如果它的第n位等于1,那么就表示值等于n的Token已經被分配出去使用了。
UserClient類的構造函數首先得到一個SharedClient對象的大小,接著再將這個大小對齊到頁面邊界,于是就得到了接下來要創建的匿名共享塊的大小cblksize。這塊匿名共享內存是一個MemoryHeapBase對象描述的,并且保存在UserClient類的成員變量mCblkHeap。MemoryHeapBase類是用來創建匿名共享內存的一個C++接口,它的實現原理可以參考Android系統匿名共享內存(Anonymous Shared Memory)C++調用接口分析一文。
UserClient類的構造函數得到了一塊匿名共享內存之后,緊接著就在這塊匿名共享內存上創建了一個SharedClient對象,并且保存在UserClient類的成員變量ctrlblk中,以便后面可以通過它來訪問Android應用程序的UI元數據。
回到SurfaceFlinger類的成員函數createClientConnection中,它將一個指向了一個UserClient對象的ISurfaceComposerClient接口返回到Android應用程序進程之后,Android應用程序進程就可以將它封裝成一個類型為BpSurfaceComposerClient的Binder代理對象。
Step 3. return BpSurfaceComposerClient
將一個Binder代理對象封裝成一個BpSurfaceComposerClient的過程可以參考前面Android應用程序與SurfaceFlinger服務的連接過程分析一文中的Step 4。
Step 4. UserClient::getControlBlock
~~~
sp<IMemoryHeap> UserClient::getControlBlock() const {
return mCblkHeap;
}
~~~
從前面的Step 2可以知道,UserClient類的成員變量mCblkHeap指向了一塊匿名共享內存,UserClient類將這塊匿名共享內存返回給Android應用程序之后,Android應用程序就會將它結構化成一個SharedClient對象來訪問,并且保存在SurfaceClient類的成員變量mControl中,這個結構化過程就可以參考前面所描述的SurfaceClient類的構造函數了。
至此,用來描述Android應用程序的UI元數據的一個SharedClient對象的創建過程就分析完了。以后當Android應用程序請求SurfaceFlinger服務創建一個Surface的時候,SurfaceFlinger服務就會從這個SharedClient對象中取出一個SharedBufferStack出來,以便可以用作這個Surface的UI元數據緩沖區。在接下來的一篇文章中,我們將詳細描述Android應用程序請求SurfaceFlinger服務創建Surface的過程,敬請期待!
- 前言
- 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)的過程分析