當前位置:成語大全網 - 書法字典 - 如何給Android添加系統服務?

如何給Android添加系統服務?

為android添加系統服務。我們以SurfaceComposer為例。

①首先提供接口文件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);

退貨服務;

}

}