首先,针对android.media.MediaPlayer进行分析。
里面有很多native代码,我们找到native_setup这个jni调用,就可以找到整个框架的入口。
我们查看
android_media_MediaPlayer_native_setup@framworks/base/media/jni/android_media_MediaPlayer.cpp
static void android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this) { LOGV("native_setup"); sp<MediaPlayer> mp = new MediaPlayer(); if (mp == NULL) { jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); return; } // create new listener and give it to MediaPlayer sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this); mp->setListener(listener); // Stow our new C++ MediaPlayer in an opaque field in the Java object. setMediaPlayer(env, thiz, mp); }
从这里的这段代码我们可以看到,android在这里实例化了一个变量mp:MediaPlayer。
并且为其设置了一个listener:JNIMediaPlayerListener
在后面我们会看到对mp的调用,现在让我们先看看MediaPlayer是什么东东。
MediaPlayer@framworks/base/include/media/mediaplayer.h
MediaPlayer@framworks/base/media/libmedia/mediaplayer.cpp
在这里我们终于找到了MediaPlayer:BnMediaPlayerClient:IMediaPlayerClient
原来他也是对Bind Native的一个封装,而他本身提供了很多方法用于访问,包括start等。下面是start的cpp代码:
status_t MediaPlayer::start() { LOGV("start"); Mutex::Autolock _l(mLock); if (mCurrentState & MEDIA_PLAYER_STARTED) return NO_ERROR; if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) { mPlayer->setLooping(mLoop); mPlayer->setVolume(mLeftVolume, mRightVolume); mCurrentState = MEDIA_PLAYER_STARTED; status_t ret = mPlayer->start(); if (ret != NO_ERROR) { mCurrentState = MEDIA_PLAYER_STATE_ERROR; } else { if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) { LOGV("playback completed immediately following start()"); } } return ret; } LOGE("start called in state %d", mCurrentState); return INVALID_OPERATION; }
原来这里又调用了mPlayer:sp<IMediaPlayer>
从这里我们发现最终的服务,还是由IMediaPlayer这个东西提供的,而IMediaPlayer@framworks/base/include/media/IMediaPlayer.h
实际上是如下定义的一个类,它继承了IInterface@framworks/base/include/binder/IInterface.h这个类(注意虽然名字是Interface,但是它确实是个类!:-))
class IMediaPlayer: public IInterface { public: DECLARE_META_INTERFACE(MediaPlayer); virtual void disconnect() = 0; virtual status_t setVideoSurface(const sp<ISurface>& surface) = 0; virtual status_t prepareAsync() = 0; virtual status_t start() = 0; virtual status_t stop() = 0; virtual status_t pause() = 0; virtual status_t isPlaying(bool* state) = 0; virtual status_t seekTo(int msec) = 0; virtual status_t getCurrentPosition(int* msec) = 0; virtual status_t getDuration(int* msec) = 0; virtual status_t reset() = 0; virtual status_t setAudioStreamType(int type) = 0; virtual status_t setLooping(int loop) = 0; virtual status_t setVolume(float leftVolume, float rightVolume) = 0; virtual status_t invoke(const Parcel& request, Parcel *reply) = 0; virtual status_t setMetadataFilter(const Parcel& filter) = 0; virtual status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata) = 0; };
为了弄清楚,在什么地方产生的mPlayer,我转而分析MediaPlayerService@framworks/base/media/libmediaplayerservice/MediaPlayerService.h
其中有如下代码
virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid); void removeMediaRecorderClient(wp<MediaRecorderClient> client); virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid); // House keeping for media player clients virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url); virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length);
原来在这个地方会创建你sp<IMediaPlayer>对象。