1、Music.apk至java MediaPlayer 至 libmedia MediaPlayer (JNI)
Start是Java空間代碼,在架構層的frameworks/base/media/java/android/media/mediaPlayer.java中,
通過JNI和android binder機制,向C++空間調用實現;向上打包成mediaplayer庫提過給應用開發使用。
/**描述: * Starts or resumes playback. If playback had previously been paused, * playback will continue from where it was paused. If playback had * been stopped, or never started before, playback will start at the * beginning. * * @throws IllegalStateException if it is called in an invalid state */ public void start() throws IllegalStateException { stayAwake(true); _start(); }
private native void _start() throws IllegalStateException;
_start是本地方法,會通過JNI調用android的實現,實現代碼位置在:
frameworks/base/media/jni/android_media_MediaPlayer.cpp
JNINativeMethod gMethods[]數組中定義了JVM和C++函數對應關係,包括函數名稱和傳遞參數對應,
如{"_start", "()V",(void *)android_media_MediaPlayer_start},
其中:
“_start”是java空間函數名稱
“()V”是java空間參數和函數類型,括弧內為參數,用;分開多個參數,括弧後面跟著函數類型,V是void意思,I是int意思等等
“(void *)android_media_MediaPlayer_start”是對應C++空間函數類型和函數名稱
static voidandroid_media_MediaPlayer_start(JNIEnv *env, jobject thiz){ LOGV("start"); sp<MediaPlayer> mp = getMediaPlayer(env, thiz); if (mp == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); return; } process_media_player_call( env, thiz, mp->start(), NULL, NULL );}
JNIEnv *env本地空間的資源,jobject thiz是java空間資源;getMediaPlayer(env, thiz)先從java空間資源中擷取對應本地資源,傳回型別為MediaPlayer指標;process_media_player_call調用MediaPlayer類的方法start。至此,已經完成從java空間的start到本地實現中的start調用關係,後面start怎麼實現就是service的事情了。
從Music.apk的方法start、pause/resume、stop,到C++實現start、pause/resume、stop的調用流程是一樣的