Android JB MediaPlayer MediaPlayerService Binder 構建 分析

    本例主要分析一下JNI 調用之後的libmedia and libmediaplayerservice, mediaplayer.cpp 中定義了playback 相關的c++ API, 可以使用這些接口編寫一些framework 級別的player 應用,當然似乎沒人這麼幹; mediaplayerservice 作爲mediaserver 的主要service 之一,在media playback 中起着至關重要的作用,其管理着衆多Player,同樣我們可以在mediaplayerservice  中添加我們自己的player. 

    mediaserver 作爲一個單獨的進程而存在,mediaplayer 又是透過怎樣的方式來獲取mediaplayerservice的服務,mediaplayerservice又是怎樣回饋信息給mediaplayer的呢?在此就不得不說binder , 非常強大的工具,站在巨人的肩膀上,使我們能夠看得更遠,以下我們將抽絲剝繭,理清楚對於BpBinder, BnBinder 的構建;

  1.  mediaplayer 繼承自 BnMediaPlayerClient and IMediaDeathNotifier,   有繼承BnMediaPlayerClient , 那麼BpMediaPlayerClient 在哪裏構造呢? IMediaDeathNotifier表示它要對遠程對象的銷燬作出反應;
  2. mediaplayerservice 繼承自 BnMediaPlayerService, 那麼mediaplayer要使用mediaplayerservice 的服務,必然要構建BpMediaPlayerService, 在哪裏構建的呢?               關注mediaplayer 中時有出現的const sp<IMediaPlayerService>& service(getMediaPlayerService());                                                                                                                            getMediaPlayerService 在IMediaDeathNotifier 中被實作,got it , 通過defaultServiceManager(), 去getService(String16("media.player")), 拿到binder, 再進一步interface_cast<IMediaPlayerService>(binder);  拿到BpMediaPlayerService;
  3. 獲取BpMediaPlayerService之後,我們就可以通過BpMediaPlayerService,跨進程調用到BnMediaPlayerService的子類mediaplayerservice, mediaplayer 中sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));  這一句開始進行create 調用,我們來到IMediaPlayerService.cpp, BpMediaPlayerService create 通過remote()->transact(CREATE, data, &reply),  觸發BnMediaPlayerService::onTransact  中的case CREATE,  首先在其中構建sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder()); OK , 我們構建出BpMediaPlayerClient,  以BpMediaPlayerClient爲參數進一步構建sp<IMediaPlayer> player = create(pid, client, audioSessionId); 在mediaplayerservice中我們完成了對於BnMediaPlayer的構建,並將其返回,  再回到BpMediaPlayerService create , 最後一句 return interface_cast<IMediaPlayer>(reply.readStrongBinder()); 以BnMediaPlayerService的reply成功的構建出了BpMediaPlayer,  此BpMediaPlayer被賦值於MediaPlayer中的mPlayer,   自此我們完成了BpMediaPlayer, BnMediaPlayer , BpMediaPlayerClient的構建;
  4. BpMediaPlayerClient位於mediaplayerservice端,其用於信息的回傳,而由於mediaplayer 繼承自BnMediaPlayerClient的緣故,對於mediaplayerservice回傳的的信息,我們會在mediaplayer notify中進行監聽,將必要的信息通過listener 進一步上傳,最後通過java 調用postEventFromNative將信息通知到apk.
  5. BpMediaPlayer 構建完成後,我們就可以在mediaplayer中通過BpMediaPlayer跨進程調用BnMediaPlayer即mediaplayerservice中class Client : public BnMediaPlayer的方法,在Client中進行setDataSource , prepare , play的動作;
  6. 在MediaPlayerService::Client中有一成員變量mClient, 實爲BpMediaPlayerClient, 兩個client的理解不一致, MediaPlayerService::Client只是相對MediaPlayerService來說,其用於處理一個instance,實際上其爲BnMediaPlayer,在這一點上理解,它是提供服務的server端; mClient 爲回傳信息而存在;
      至此,我們基本理清了mediaplayer與mediaplayerservice之間的BpBinder 以及BnBinder的構建;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章