Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Multimedia框架總結(六)C++中MediaPlayer的C/S架構

Android Multimedia框架總結(六)C++中MediaPlayer的C/S架構

編輯:關於Android編程

前面幾節中,都是通過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:

舉例setDataSource方法在mediaplayer.cpp之後發生了什麼? Client到底是什麼? Client及MediaPlayer是什麼一種關系? IMediaPlayer.h,mediaplayer.h,IMediaPlayerClient分別做什麼?

舉例setDataSource方法在mediaplayer.cpp之後發生了什麼?

先看下setDataSource方法:

這裡寫圖片描述

對應看下MediaPlayerService.cpp中createt函數,這裡說下MediaPlayerService.cpp位置,6.0源碼中是在frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp中。如下:

這裡寫圖片描述

在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,在兩個進程間通信。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMyBpZD0="client到底是什麼">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中的

這裡寫圖片描述

語句相當於

這裡寫圖片描述

即player最終是用Client對象來初始化,可以直接認為player==client

Client及MediaPlayer是什麼關系?

這是候問題來了?在C++中,這個Client及MediaPlayer又是什麼一種關系呢?

Client是MediaPlayerService內部的一個類,我們從上面代碼已知,因為MediaPlayerService運行在服務端,故Client也是運行在服務端。 Client在MediaPlayerService.h中,那接著看下MediaPlayerService中的實現,實現過程中調用過了MediaPlayerService類的一些函數,同樣回到setDataSource

這裡寫圖片描述
這裡寫圖片描述

接下來看MediaPlayer中,以下代碼中在frameworks/av/include/media/mediaplayer.h中:

這裡寫圖片描述
這裡寫圖片描述

這裡函數和Client中的函數時一一對應的,兩者通過Client的代理類聯系在了一起。

這裡寫圖片描述
這裡寫圖片描述

上面兩個函數,一個是MediaPlayer的setDataSouree,然後裡面會調到attachNewPlayer函數,這個函數最終會調用到服務端Client的對應的函數,

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)的接口。

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