Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 初級開發 >> android binder機制(七)

android binder機制(七)

編輯:初級開發

接上,其實BnMediaPlayerService->onTransact函數的結構也很簡單,就是switch...case...接收不同的請求執行不同的代碼調用。到這裡就水落石出了,我們的Binder機制就基本介紹完畢,呼呼~

17、客戶端與service的交互(MediaPlayerClIEnt與MediaPlayerService)

我們以下面為例:

android binder機制(七)

上面就是getMediaPlayerService的一個case:

1、創建serviceManager

2、sm->getService("media.player");來獲得Binder對象

3、使用interface_cast,將這個binder轉化成BpMediaPlayerService。並且BpMediaPlayerService利用這個binder與BnMediaPlayerService進行通信,

要注意的是:如果自己寫一個純C++程序來調用getMediaPlayerService方法可以獲取到service麼?答案是不行的,因為還沒有打開BINDER驅動。之所以在Java應用程序中可以直接使用getService是因為GOOGLE已經幫你封裝好喽~所以純native應該這樣處理~

sp<ProcessState>proc(ProcessState::self()); //打開Binder驅動

getMediaPlayerService();

ProcessState::self()->startThreadPool(); //開啟消息循環,檢測BnMediaPlayerService傳來的消息

18、實現自己的service,如果寫C++文件的話,肯定需要類似main_mediaservice.cpp那樣的

int main()

  sp<ProcessState>proc(ProcessState::self());

  sp<IServiceManager> sm =defaultServiceManager();

  sm->addService(“service.name”,newXXXService());

  ProcessState::self()->startThreadPool();

  IPCThreadState::self()->joinThreadPool();

(1) 第一步,需要為這個接口定義一個繼承自IInterface的接口類,假設叫做IMyService。

(2) 第二步,需要定義兩個binder類,其中一個是代理類BpMyService,需繼承自BpInterface;另一個是實現類 BnMyService,需繼承自BnInterface,BnMyService只不過是把IMyService加入到BInder架構中,而不參與實際的getXXX和setXXX應用層邏輯

(3) 第三步,定義BnMyService的子類,這個子類可以是任何名字,比如就叫MyService,在其中真正實現接口所提供的各個函數。

(4) 第四步,創建MyService的實例,注冊到服務管理器(如IMediaPlayerService),也可以在其它接口的函數中創建(如IMediaPlayer)

19、漫長的一個月,終於將Binder模模糊糊的看完了~回想起之前看的一些疑惑的地方現在已經迎刃而解,之前繞了半天的圈其實不過也只是做了一個操作而已。那麼就再做個徹底的總結吧

【1】我們的入口點是在main_mediaserver.cpp中,我不得不又把這個CPP拿上來看~

int main(int argc,char** argv)

  sp<ProcessState>proc(ProcessState::self());     //在ProcessState構造函數中,打開Binder設備,並用int mDriverFD來記錄打開設備後的返回值,使用mmap將此mDriverFD放入內存共享處。與此同時又寫了些關於mmap操作的東西~

  sp<IServiceManager> sm =defaultServiceManager(); 

//A、在defaultServiceManager()中,創建了BpBinder。得到等式:sp<IServiceManager> sm = interface_cast<IServiceManager>(new BpBinder(0)); 

B、BpBinder構造函數中IPCThreadState::self()->incWeakHandle(handle);來創建IPCThreadState(一個線程只能有一個IPCThreadState,因為是TLS),並增加強引用。與此同時又寫了些強弱引用的東西

C、interface_cast(位於IInterface.h)是個宏定義,等價為sp<IServiceManager> sm = IServiceManager.asInterface(new BpBinder(0));,又等價為sp<IServiceManager> sm = new BpServiceManager(new BpBinder(0));

  MediaPlayerService::instantiate();

//A、用BpServiceManager.addService(MediaPlayerService);因為MediaPlayerService又繼承BnMediaPlayerService。所以等價為

BpServiceManager.addService(BnMediaPlayerService);

B、在addService方法中,使用了BpBinder->transact(其實是IPCThreadState做操作)將service封裝成parcel包進行傳輸==>使用ioctl與binder設備打交道(ioctl(mDriverFD,BINDER_WRITE_READ,&bwr)),至此就發送給BINDER設備信息

C、而service_manager.c充當BnMediaServiceManager,開啟一個binder_loop以便監聽ioctl中是否有信息,如果有信息則由handle負責處理,將service登記到svclist中。

D、並且後來分析了從Java層到JNI層的addService

  ProcessState::self()->startThreadPool();

  IPCThreadState::self()->joinThreadPool();

//這兩句話其實最後都是IPCThreadState::self()->joinThreadPool();只不過是兩個不同的IPCThreadState(因為TLS)

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved