①首先提供接口文件ISurfaceComposer.h
//framework \ native \ include \ GUI \ isurface composer . h
//首先是接口,c++實現是虛函數。
class ISurfaceComposer:公共接口{
公共:
DECLARE _ META _ INTERFACE(surface composer);
setTransactionState()的標誌
枚舉{
eSynchronous = 0x01,
eAnimation = 0x02,
};
枚舉{
eDisplayIdMain = 0,
};
/*創建與表面拋油環的連接,需要
* ACCESS_SURFACE_FLINGER權限
*/
虛擬sp & ltISurfaceComposerClient & gtcreate connection()= 0;
}
②建立BnSurfaceComposer。
要建立BnSurfaceComposer,您需要重寫BBinder的onTransact函數
類bnsurface composer:public bn interface & lt;ISurfaceComposer & gt{
公共:
枚舉{
//註意:BOOT_FINISHED必須保持該值,它是從
// Java by ActivityManagerService。
BOOT _ FINISHED = I binder::FIRST _ CALL _ TRANSACTION,
創建連接,
創建圖形緩沖區分配,
創建顯示事件連接,
創建_顯示,
銷毀_顯示,
GET _ BUILT _ IN _ DISPLAY,
設置交易狀態,
AUTHENTICATE_SURFACE
空白,
未隱藏,
獲取顯示信息,
連接顯示,
捕捉屏幕,
};
虛擬狀態合同(uint32_t代碼,const Parcel & amp數據,
Parcel* reply,uint 32 _ t flags = 0);
};
BP XXX的實現
在framework \ native \ libs \ GUI \ isurface composer . CPP中,
//Bp實現,代理端
類BP surface composer:public BP interface & lt;ISurfaceComposer & gt
{
公共:
bpsurface composer(const sp & lt;IBinder & gt& ampimpl)
:BpInterface & ltISurfaceComposer & gt(實施)
{
}
//代理接口
虛擬sp & ltISurfaceComposerClient & gt創建連接()
{
uint 32 _ t n;
包裹數據,回復;
data . write interface token(isurface composer::get interface descriptor());
remote()-& gt;transact(bnsurface composer::CREATE _ CONNECTION,data,& amp回復);
返回interface _ cast & ltISurfaceComposerClient & gt(reply . readstrong binder();
}
}
bn XXX的實現
//Bn端,也就是服務器端。
status _ t bnsurface composer::on transact(
uint32_t代碼,const包裹& amp數據、包裹*回復、uint32_t標誌)
{
開關(代碼){
案例創建_連接:{
CHECK _ INTERFACE(isurface composer,data,reply);
//createConnection是服務器端的實現函數。
sp & ltIBinder & gtb = create connection()-& gt;as binder();
回復-& gt;writestonbinder(b);
返回NO _ ERROR
}
默認值:{
return BBinder::onTransact(代碼、數據、回復、標誌);
}
}
//應該無法訪問
返回NO _ ERROR
}
⑤掛號服務。
通過上述步驟完成服務的建立後,我們需要在服務管理器中註冊服務。
class SurfaceFlinger:公共BnSurfaceComposer,
//在framework \ native \ services \ surface flinger \ main _ surface flinger . CPP中,
//發布表面拋出器
sp & ltIServiceManager & gtsm(defaultServiceManager());
sm-& gt;addService(string 16(surface Flinger::get service name(),flinger,false);
⑥使用服務
//首先,獲取代理BpSurfaceComposer。
sp & ltISurfaceComposer & gtcomposer(composer service::getcomposer service());
//直接調用代理BpSurfaceComposer的接口。
sp & ltIGraphicBufferAlloc>。alloc(作曲家-》;createGraphicBufferAlloc());
getComposerService()的實現是,
/*static*/ sp<。ISurfaceComposer & gtComposerService::getComposerService(){
作曲服務公司。instance = composer service::getInstance();
mutex::Autolock _ l(instance . m lock);
if(instance . mcomposerservice = = NULL ){
ComposerService::getInstance()。connect locked();
assert(instance . mcomposerservice!= NULL);
a logd(“composer service reconnected“);
}
返回instance.mComposerService
}
void composer service::connect locked(){
const string 6 5438+06 name(“surface flinger“);
//獲取服務,返回的mComposerService為BpSurfaceComposer。使用Bp,您可以直接調用代理接口。
while(get service(name,& ampmComposerService)!= NO_ERROR)
us LEEP(25萬);
}
assert(mComposerService!= NULL);
//創建死亡偵聽器。
class death observer:public I binder::death recipient {
作曲服務公司。mComposerService
虛擬空綁定(const wp & ltIBinder & gt& amp誰){
ALOGW(“ComposerService remote(surface flinger)已死亡【%p】“,
who . unsafe _ get());
mcomposerservice . composerservicedied();
}
公共:
死亡觀察者(ComposerService & ampmgr):mComposerService(mgr){ }
};
mDeathObserver = new death observer(* const _ cast & lt;ComposerService * & gt(這個);
mComposerService-& gt;as binder()-& gt;linkToDeath(mDeathObserver);
}
在java中添加服務
為了方便開發者,Android提供了AIDL工具,這簡化了編寫服務的難度。讓我們以添加TestService為例。
①寫入AIDL文件
打包android.app
接口ITestService {
boolean enableWifi(布爾啟用);
}
TestService的AIDL文件提供了壹個接口enableWifi()。
②創建TestService服務。
TestService服務需要繼承ITestService。存根類,通過AIDL工具處理①中的AIDL文件生成。
類TestService擴展了ITestService。存根{
//實現接口
公共布爾啟用Wifi(布爾啟用)
{
......
}
}
③將服務名稱字符串添加到Context.java。
//將服務名稱字符串添加到Context.java。
公共靜態最終字符串TEST _ SERVICE =“my _ TEST“;
④向ServiceManager註冊服務。
java中的大多數系統服務都是向SystemServer中的服務管理器註冊的。
//ServiceManager註冊服務
//在SystemServer.java,模仿向ServiceManager添加服務的其他方法。
嘗試{
TestService my service = new TestService(context);
ServiceManager.addService(上下文。TEST_SERVICE,my SERVICE);
}接球(可投擲的e ){
reportWtf(“註冊我的測試服務失敗“,e);
}
⑤創建服務對應的管理器。
對於每個服務,通常都有壹個相關的經理。管理器提供API供應用程序使用,成為SDK的壹部分,並充當應用程序和遠程服務之間的橋梁。管理器和服務中的接口必須是壹對壹的。
公共類TestServiceManager{
private final itest service m service;
私有最終上下文mContext
//構造函數中傳遞的服務實際上是BpTestService。
TestServiceManager(上下文Context,ITestService服務){
mContext =上下文;
mService =服務;
}
公共布爾啟用Wifi(布爾啟用){
嘗試{
返回mService.enableWifi(已啟用);
} catch(remote exception ex ){
}
返回false
}
}
到目前為止,我們只註冊了該服務,但還沒有使用它。我們如何使用它?
⑥在contextimpl中註冊管理器。
壹旦我們實現了服務和相應的管理器,我們需要壹種在應用程序中調用它們的方法。如前所述,Manager將成為SDK的壹部分供我們調用,那麽Manager和Service是如何關聯的呢?首先,我們需要在執行上下文中註冊我們的服務和mangager,即contextImpl。
register SERVICE(TEST _ SERVICE,new SERVICE fetcher(){
公共對象創建服務(context impl CTX ){
I binder b = SERVICE manager . get SERVICE(TEST _ SERVICE);
//as interface(BP binder)後跟BpTestService。
ITestService服務= ITestService。stub . as interface(b);
//創建TestServiceManager,第二個參數是BpBpTestService。
返回新的TestServiceManager(CTX . getoutercontext(),service);
}});
registerService的第二個參數是ServiceFetcher對象,其中創建了壹個新的ServiceFetcher類,並在調用時直接重寫了createService方法。
ContextImpl.java中registerService()方法的核心是將servicename和ServiceFetcher對象放入壹個散列鍵值對中。
私有靜態void registerService(字符串serviceName,service fetcher fetcher ){
如果(!(靜態服務提取器的提取器實例){
fetch er . mcontextcacheindex = snextpercontextservicecacheindex++;
}
SYSTEM _ SERVICE _ map . put(SERVICE name,fetcher);
}
APP如何使用服務?
那麽這個app是怎麽叫的呢?
導入Android . app . testservicemanager;
導入Android . content . context;
TestServiceManager mTestServiceManager;
mTestServiceManager =(TestServiceManager)Context . getsystemservice(Context。TEST _ SERVICE);
然後直接調用TestServiceManager中的方法,其中的奧秘需要在getSystemService函數下分析。
在ContextImpl.java,
@覆蓋
公共對象getSystemService(字符串名稱){
ServiceFetcher fetcher = SYSTEM _ SERVICE _ map . get(name);
//從ServiceFetcher獲取服務
return fetcher == null?null:fetch er . get service(this);
}
getService()函數的核心是上面重寫的createService()函數,它返回TestServiceManager對象,因此Manager對象是通過context.getSystemService返回的。
公共對象獲取服務(context impl CTX ){
數組列表& lt對象& gtcache = ctx.mServiceCache
對象服務;
同步(緩存){
if(cache . size()= = 0 ){
//首次訪問時初始化緩存向量。
//此時sNextPerContextServiceCacheIndex
//是潛在服務的數量
//緩存的每上下文。
for(int I = 0;我& ltsNextPerContextServiceCacheIndex;i++) {
cache . add(null);
}
}否則{
service = cache . get(mContextCacheIndex);
如果(服務!= null) {
退貨服務;
}
}
//調用重載的createService函數,返回的對象為TestServiceManager。
service = createService(CTX);
cache . set(mContextCacheIndex,service);
退貨服務;
}
}