編輯:初級開發
17、客戶端與service的交互(MediaPlayerClIEnt與MediaPlayerService)
我們以下面為例:
上面就是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. 一些常用的公共屬性介紹1) layout_width - 寬fill_parent: 寬度和父元素相同,wrap_content: 寬度隨本身的內容所調整,或者指
從學習搭環境到開發,雖然也遇到些讓人糾結的問題,還好都一一解決了。言歸正轉,這次寫的是一個Demo似的小應用,簡單得不能再簡單了,一共就三個類,主類Bubble繼承於A
RelativeLayout關系布局:在form中的用法:@[+][package:]type:name (@id/vIEwName)在主題模式form中的用法: ?[