前面幾節中,都是經過java層調用到jni中,jni向下到c++層並未介紹
看下Java層一個方法在c++層 MediaPlayer後續過程
frameworks/av/media/libmedia/MediaPlayer.cpp
找一個咱們以前熟悉的setDataResource方法看下C/S模式的過程,亦可參考Android Multimedia框架總結(四)MediaPlayer中從Java層到C++層類關係及prepare及以後其餘過程當中的圖,瞭解總體上C/S架構。先看下Agenda:java
舉例setDataSource方法在mediaplayer.cpp以後發生了什麼?
Client究竟是什麼?
Client及MediaPlayer是什麼一種關係?
IMediaPlayer.h,mediaplayer.h,IMediaPlayerClient分別作什麼?
舉例setDataSource方法在mediaplayer.cpp以後發生了什麼?
先看下setDataSource方法:android
對應看下MediaPlayerService.cpp中createt函數,這裏說下MediaPlayerService.cpp位置,6.0源碼中是在frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp中。以下:c++
在new Client中,有一個IPCThreadState,這裏介紹下: 在Android中ProcessState是客戶端和服務端公共的部分,做爲Binder通訊的基礎,ProcessState是一個singleton類,每一個
進程只有一個對象,這個對象負責打開Binder驅動,創建線程池,讓其進程裏面的全部線程都能經過Binder通訊。
與之相關的是IPCThreadState,每一個線程都有一個IPCThreadState實例登記在Linux線程的上下文附屬數據中,主要負責
Binder的讀取,寫入和請求處理框架。IPCThreadState在構造的時候獲取進程的ProcessState並記錄在本身的成員變量mProcess中,經過mProcess能夠得到Binder的句柄。詳細瞭解ProcessStata及IPCThreadState源碼,能夠參考:《Binder中的ProcessState和IPCThreadState分析》,寫的很不錯,IPCThreadState經過IPCThreadState::transact把data,及handle等填充入binder_transaction_data,在兩個進程間通訊。架構
Client究竟是什麼?
這裏這個Client究竟是什麼?咱們又得追蹤下,在frameworks/av/media/libmediaplayerservice/MediaPlayerService.h以下:框架
以上代碼沒有省略,是由於確實對咱們理解從Java層過來的MediaPlayer相關方法,在這都有對應。若是還記得前面《Android Multimedia框架總結(四)MediaPlayer中從Java層到C++層類關係及prepare及以後其餘過程》文章中那個圖的話,能夠從總體上理解這個Client屬於什麼角色及位置。繼承BnMediaPlayer,幷包含了IMediaPlayer相關接口。
總結下上面代碼:Client類的繼承關係爲:Client->BnMediaPlayer->IMediaPlayer分析上面代碼,能夠看出create方法,是構造了一個Client對象,而且將此client對象添加到mediapalyerservice類的全局列表中:mClients,是一個SortedVector,緊接着執行player->setDataSource(url, headers),即Clients::setDataSource,所以在setDataSource中的函數
語句至關於ui
即player最終是用Client對象來初始化,能夠直接認爲player==client
本文出自逆流的魚yuiop:http://blog.csdn.net/hejjunlin/article/details/52435789url
Client及MediaPlayer是什麼關係?
這是候問題來了?在C++中,這個Client及MediaPlayer又是什麼一種關係呢?.net
Client是MediaPlayerService內部的一個類,咱們從上面代碼已知,由於MediaPlayerService運行在服務端,故Client也是運行在服務端。
Client在MediaPlayerService.h中,那接着看下MediaPlayerService中的實現,實現過程當中調用過了MediaPlayerService類的一些函數,一樣回到setDataSource線程
接下來看MediaPlayer中,如下代碼中在frameworks/av/include/media/mediaplayer.h中:
這裏函數和Client中的函數時一一對應的,二者經過Client的代理類聯繫在了一塊兒。
上面兩個函數,一個是MediaPlayer的setDataSouree,而後裏面會調到attachNewPlayer函數,這個函數最終會調用到服務端Client的對應的函數,
本文出自逆流的魚yuiop:http://blog.csdn.net/hejjunlin/article/details/52435789
IMediaPlayer.h,mediaplayer.h,IMediaPlayerClient分別作什麼?
到這裏,可能有人會想:IMediaPlayer.h,及mediaplayer.h的區別是什麼?總結主要以下(另加一個IMediaPlayerClient.h,一塊兒介紹):
從包結構:首先IMediaPlayer和IMediaPlayerClient.h都是在frameworks/av/media/libmedia包下,而mediaplayer.h是在/av/include/media包下。(前面已有代碼貼出)
從功能上看:它們擔當職責也不同
這裏貼出IMediaPlayer.h及IMediaPlayerClient.h代碼:
IMediaPlayer.h位於frameworks/av/media/libmedia下:
IMediaPlayer.h中定義的基本上都是虛函數,而咱們知道虛函數在C++中就是實現多態性(Polymorphism),多態性是將接口與實現進行分離;用形象的語言來解釋就是實現以共同的方法,但因個體差別而採用不一樣的策略。因此它的功能是一個實現MediaPlayer功能的接口,看到那個onTransact方法,天然聯想Binder通訊,把底層的Parcel指針類型數據向上層向另外一個進程中傳遞。
再看下IMediaPlayerClient.h,一樣位於frameworks/av/media/libmedia下:
上面代碼總結爲:在內部定義一個BpMediaPlayerClient(也就是Client的父類),而後它也有一個onTransact,通常onXXX都是屬於背動回調過來的,不是由本身控制,如Activity中onCreate,onPause,onStart,這些都是在其餘地方處理,通知到Actvitity中的。這裏也是同樣,onTransact做爲Binder通訊中的回調方法,前面《Android Multimedia框架總結(四)MediaPlayer中從Java層到C++層類關係及prepare及以後其餘過程》中介紹到player其實是C/S模式總體,IMediaPlayerClient.h的功能是描述一個MediaPlayer客戶端的接口。
最後總結下:mediaplayer.h的功能是對外(jni層)的接口類,它最主要是定義了一個MediaPlayer類(C++層),咱們在android_media_MediaPlayer.cpp中就引入了media/mediaplayer.h,IMediaPlayer.h則是一個實現MediaPlayer(C++層)功能的接口,而IMediaPlayerClient.h的功能是描述一個MediaPlayer客戶端(這裏暫理解爲前面說的Client)的接口。