Android学习(五)由MediaPlayer切入(1)

MediaPlayer切入

MediaPalyer的基本用法:

private MediaPlayer mp new MediaPlayer();

开始播放:

mp.setDataSource("/sdcard/test.mp3");

mp.prepare();

mp.start();

播放完成监听:

mp.setOnCompletionListener(new OnCompletionListener(){

  @Override

  public void onCompletion(MediaPlayer mp) {

       mp.release();

     }

  });

播放暂停:

mp.pause();

播放终止:

mp.stop();

 

 

  1. MediaPlayer的构造函数

进入到MediaPlayer的源码部分,从第一步构造函数开始:

/*\frameworks\base\media\java\android\media\MediaPlayer.java*/

    /**

     * Default constructor. Consider using one of the create() methods for

     * synchronously instantiating a MediaPlayer from a Uri or resource.

     * <p>When done with the MediaPlayer, you should call  {@link #release()},

     * to free the resources. If not released, too many MediaPlayer instances may

     * result in an exception.</p>

     */

    public MediaPlayer() {

 

        Looper looper;à 得到当前线程的Looper, 并创建EventHandler对象

        if ((looper = Looper.myLooper()) != null) {

            mEventHandler = new EventHandler(this, looper);

        } else if ((looper = Looper.getMainLooper()) != null) {

            mEventHandler = new EventHandler(this, looper);

        } else {

            mEventHandler = null;

        }

 

        /* Native setup requires a weak reference to our object.

         * It's easier to create it here than in C++.

         */

        native_setup(new WeakReference<MediaPlayer>(this));

    }

首先看一下EventHandler的定义:

/*\frameworks\base\media\java\android\media\MediaPlayer.java*/

    private class EventHandler extends Handler

    {

        private MediaPlayer mMediaPlayer;

 

        public EventHandler(MediaPlayer mp, Looper looper) {

            super(looper);

            mMediaPlayer = mp;

        }

 

        @Override

        public void handleMessage(Message msg) {

            if (mMediaPlayer.mNativeContext == 0) {

                Log.w(TAG, "mediaplayer went away with unhandled events");

                return;

            }

            switch(msg.what) {

            case MEDIA_PREPARED:

                if (mOnPreparedListener != null)

                    mOnPreparedListener.onPrepared(mMediaPlayer);

                return;

 

            case MEDIA_PLAYBACK_COMPLETE:

                if (mOnCompletionListener != null)

                    mOnCompletionListener.onCompletion(mMediaPlayer);

                stayAwake(false);

                return;

可见EventHandler是一个handler,根据收到的不同Message对上层进行回调。

再看一下native_setup函数定义:

/* \frameworks\base\media\java\android\media\MediaPlayer.java*/

private native final void native_setup(Object mediaplayer_this);

 

可见是一个native函数调用,找到相关的实现:

/*\frameworks\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);à SetIntField(thiz, fields.context, (int)player.get()),将创建的playerJava层的mNativeContext联系起来。mNativeContextJava层的EventHandler.handleMessage中判断是否是对应的底层mediaplayer返回的信息。如果不是,就不处理。

}

查看一下JNI层的listerner定义:

/*\frameworks\base\media\jni\android_media_MediaPlayer.cpp*/

// ----------------------------------------------------------------------------

// ref-counted object for callbacks

class JNIMediaPlayerListener: public MediaPlayerListener

{

public:

    JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz);

    ~JNIMediaPlayerListener();

    void notify(int msg, int ext1, int ext2);

private:

    JNIMediaPlayerListener();

    jclass      mClass;     // Reference to MediaPlayer class

    jobject     mObject;    // Weak ref to MediaPlayer Java object to call on

};

 

JNIMediaPlayerListener::JNIMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz)

{

 

    // Hold onto the MediaPlayer class for use in calling the static method

    // that posts events to the application thread.

    jclass clazz = env->GetObjectClass(thiz);

    if (clazz == NULL) {

        LOGE("Can't find android/media/MediaPlayer");

        jniThrowException(env, "java/lang/Exception", NULL);

        return;

    }

    mClass = (jclass)env->NewGlobalRef(clazz);

 

    // We use a weak reference so the MediaPlayer object can be garbage collected.

    // The reference is only used as a proxy for callbacks.

    mObject  = env->NewGlobalRef(weak_thiz);

}

 

JNIMediaPlayerListener::~JNIMediaPlayerListener()

{

    // remove global references

    JNIEnv *env = AndroidRuntime::getJNIEnv();

    env->DeleteGlobalRef(mObject);

    env->DeleteGlobalRef(mClass);

}

 

void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2)

{

    JNIEnv *env = AndroidRuntime::getJNIEnv();

    env->CallStaticVoidMethod(mClass, fields.post_event, mObject, msg, ext1, ext2, 0);

}

作用就是将JNI层的消息能上传到java层。

sp<MediaPlayer> mp = new MediaPlayer();的定义:

/*\frameworks\av\media\libmedia\mediaplayer.cpp*/

MediaPlayer::MediaPlayer()

{

    ALOGV("constructor");

    mListener = NULL;

    mCookie = NULL;

    mStreamType = AUDIO_STREAM_MUSIC;

    mCurrentPosition = -1;

    mSeekPosition = -1;

    mCurrentState = MEDIA_PLAYER_IDLE;

    mPrepareSync = false;

    mPrepareStatus = NO_ERROR;

    mLoop = false;

    mLeftVolume = mRightVolume = 1.0;

    mVideoWidth = mVideoHeight = 0;

    mLockThreadId = 0;

    mAudioSessionId = AudioSystem::newAudioSessionId();

    AudioSystem::acquireAudioSessionId(mAudioSessionId);

    mSendLevel = 0;

    mRetransmitEndpointValid = false;

}

 

mAudioSessionId = AUdioSystem::newAudioSessionId();,得到新的AudioSessionId

/*\frameworks\av\media\libmedia\AudioSystem.cpp*/

int AudioSystem::newAudioSessionId() {

    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();

    if (af == 0) return 0;

    return af->newAudioSessionId();

}

 

AudioSystem::get_audio_flinger();获取AudioFlingerBpBinder

/*\frameworks\av\media\libmedia\AudioSystem.cpp*/

sp<IAudioFlinger> AudioSystem::gAudioFlinger;

 

const sp<IAudioFlinger>& AudioSystem::get_audio_flinger()

{

    Mutex::Autolock _l(gLock);

    if (gAudioFlinger == 0) {

        sp<IServiceManager> sm = defaultServiceManager();

        sp<IBinder> binder;

        do {

            binder = sm->getService(String16("media.audio_flinger"));

            if (binder != 0)

                break;

            ALOGW("AudioFlinger not published, waiting...");

            usleep(500000); // 0.5 s

        } while (true);

        if (gAudioFlingerClient == NULL) {

            gAudioFlingerClient = new AudioFlingerClient();

        } else {

            if (gAudioErrorCallback) {

                gAudioErrorCallback(NO_ERROR);

            }

        }

        binder->linkToDeath(gAudioFlingerClient);

        gAudioFlinger = interface_cast<IAudioFlinger>(binder);

        gAudioFlinger->registerClient(gAudioFlingerClient);

    }

    ALOGE_IF(gAudioFlinger==0, "no AudioFlinger!?");

 

    return gAudioFlinger;

}

这里与AudioFlinger服务发生联系,暂且不理,以分析MediaPlayerService为主。

暂且知道通过audiosessionId,将mediaplayeraudioflinger绑定起来。每个audiosession和一个pid对应,组成了一个AudioSessionRefAudioSessionRefs队列维护当前系统中运行的audiosession

  1. mp.setDataSource("/sdcard/test.mp3");

 

API中的setDataSource

/*\frameworks\base\media\java\android\media\MediaPlayer.java*/

    public void setDataSource(String path)

            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {

        setDataSource(path, null, null);

}

 

private native void _setDataSource(FileDescriptor fd, long offset, long length)

            throws IOException, IllegalArgumentException, IllegalStateException;

虽然进行了多种封装,但最终还是调用一个Native函数:

/*\frameworks\base\media\jni\android_media_MediaPlayer.cpp*/

static void

android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)

{

    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);

    if (mp == NULL ) {

        jniThrowException(env, "java/lang/IllegalStateException", NULL);

        return;

    }

 

    if (fileDescriptor == NULL) {

        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);

        return;

    }

    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    ALOGV("setDataSourceFD: fd %d", fd);

    process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );

}

/*\frameworks\av\media\libmedia\mediaplayer.cpp*/

status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)

{

    ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);

    status_t err = UNKNOWN_ERROR;

    const sp<IMediaPlayerService>& service(getMediaPlayerService());

    if (service != 0) {

        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));

        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||

            (NO_ERROR != player->setDataSource(fd, offset, length))) {

            player.clear();

        }

        err = attachNewPlayer(player);

    }

    return err;

}

看看MediaPlayer的定义:

class MediaPlayer : public BnMediaPlayerClient,

                    public virtual IMediaDeathNotifier

所以getMediaPlayerService()函数定义在IMediaDeathNotifier中:

/*\frameworks\av\media\libmedia\IMediaDeathNotifier.cpp*/

IMediaDeathNotifier::getMediaPlayerService()

{

    ALOGV("getMediaPlayerService");

    Mutex::Autolock _l(sServiceLock);

    if (sMediaPlayerService == 0) {

        sp<IServiceManager> sm = defaultServiceManager();

        sp<IBinder> binder;

        do {

            binder = sm->getService(String16("media.player"));

            if (binder != 0) {

                break;

            }

            ALOGW("Media player service not published, waiting...");

            usleep(500000); // 0.5 s

        } while (true);

 

        if (sDeathNotifier == NULL) {

            sDeathNotifier = new DeathNotifier();

        }

        binder->linkToDeath(sDeathNotifier);

        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

    }

    ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");

    return sMediaPlayerService;

}

注意这里的defaultServiceManager()函数,它会返回一个IServiceManager对象,通过它来与ServiceManager进程进行交互。

/*\frameworks\native\libs\binder\IServiceManager.cpp*/

sp<IServiceManager> defaultServiceManager()

{

    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;   

    {

        AutoMutex _l(gDefaultServiceManagerLock);

        while (gDefaultServiceManager == NULL) {

            gDefaultServiceManager = interface_cast<IServiceManager>(

                ProcessState::self()->getContextObject(NULL));

            if (gDefaultServiceManager == NULL)

                sleep(1);

        }

    }

   

    return gDefaultServiceManager;

}

看看ProcessState::self()->getContextObject(NULL)前面已经分析过,返回一个new BpBinder(handle);handle值为0

 

看看interface_cast的定义:

/*\frameworks\native\include\binder\IInterface.h*/

template<typename INTERFACE>

inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)

{

    return INTERFACE::asInterface(obj);

}

定义的是一个函数模版,调用后相当于调用IServiceManager:: asInterface(obj),然而这又是在哪里定义的呢?

/*\frameworks\native\libs\binder\IServiceManager.h*/

class IServiceManager : public IInterface

{

public:

    DECLARE_META_INTERFACE(ServiceManager);

有这样一个宏定义,这个宏又是在哪里呢?

/*\frameworks\native\include\binder\IInterface.h*/

#define DECLARE_META_INTERFACE(INTERFACE)                               \

    static const android::String16 descriptor;                          \

    static android::sp<I##INTERFACE> asInterface(                       \

            const android::sp<android::IBinder>& obj);                  \

    virtual const android::String16& getInterfaceDescriptor() const;    \

    I##INTERFACE();                                                     \

    virtual ~I##INTERFACE();                                            \

DECLARE_META_INTERFACE(ServiceManager)定义转意:

static const android::String16 descriptor;à定义一个描述符字符串

 

static android::sp<IServiceManager> asInterface(const android::sp<android::IBinder>& obj);à定义一个asInterface函数

 

virtual const android::String16& getInterfaceDescriptor() const;

 

IServiceManager();

 

virtual ~IServiceManager();

 

IServiceManager中还调用了一个宏:IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");查看这个宏的定义:

/*\frameworks\native\include\binder\IInterface.h*/

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \

    const android::String16 I##INTERFACE::descriptor(NAME);             \

    const android::String16&                                            \

            I##INTERFACE::getInterfaceDescriptor() const {              \

        return I##INTERFACE::descriptor;                                \

    }                                                                   \

    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \

            const android::sp<android::IBinder>& obj)                   \

    {                                                                   \

        android::sp<I##INTERFACE> intr;                                 \

        if (obj != NULL) {                                              \

            intr = static_cast<I##INTERFACE*>(                          \

                obj->queryLocalInterface(                               \

                        I##INTERFACE::descriptor).get());               \

            if (intr == NULL) {                                         \

                intr = new Bp##INTERFACE(obj);                          \

            }                                                           \

        }                                                               \

        return intr;                                                    \

    }                                                                   \

    I##INTERFACE::I##INTERFACE() { }                                    \

    I##INTERFACE::~I##INTERFACE() { }                                   \

同样转意如下:

const android::String16 IServiceManager::descriptor("android.os.IServiceManager");

 

const android::String16& IServiceManager::getInterfaceDescriptor() const

      return IServiceManager::descriptor;

}

 

android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)

{

      android::sp<IServiceManager> intr;

      if (obj != NULL)

      {

           intr = static_cast<IServiceManager *>(obj->queryLocalInterface(IServiceManager::descriptor).get()); 

           if (intr == NULL)

           {

              intr = new BpServiceManager(obj);

           }

      }

      return intr;                                                  

}                                                                

 

IServiceManager::IServiceManager () { }                                  

 

IServiceManager::~ IServiceManager() { }

 

所以通过gDefaultServiceManager = interface_cast<IServiceManager>(

                ProcessState::self()->getContextObject(NULL));

interface_cast的调用返回一个new BpServiceManager(obj);这里的obj就是ProcessState::self()->getContextObject(NULL)返回是一个new BpBinder()

看看BpServiceManager的代码:

/*\frameworks\native\libs\binder\IServiceManager.cpp*/

class BpServiceManager : public BpInterface<IServiceManager>

{

public:

    BpServiceManager(const sp<IBinder>& impl)

        : BpInterface<IServiceManager>(impl)

    {

    }

看看BpInterface的定义:

/*\frameworks\native\include\binder\IInterface.h*/

template<typename INTERFACE>

class BpInterface : public INTERFACE, public BpRefBase

{

public:

                                BpInterface(const sp<IBinder>& remote);

 

protected:

    virtual IBinder*            onAsBinder();

};

 

template<typename INTERFACE>

inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)

    : BpRefBase(remote)

{

}

是一个模版类,构造函数调用父类BpRefBase的构造函数。

 

看看BpRefBase的构造函数:

/*\Android4.4\frameworks\native\libs\binder\Binder.cpp*/

BpRefBase::BpRefBase(const sp<IBinder>& o)

    : mRemote(o.get()), mRefs(NULL), mState(0)

{

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

 

    if (mRemote) {

        mRemote->incStrong(this);           // Removed on first IncStrong().

        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.

    }

}

BpServiceManager的一个变量mRemote指向了一个BpBinder,通过defaultServiceManager()函数的调用返回一个BpServiceManager对象,它的mRemote值是个BpBinder类型(它的handle值为0)。

 

转载于:https://my.oschina.net/honeyandroid/blog/506410

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Kotlin MediaPlayer 是应用程序开发时可以使用的多媒体播放器库。它提供了播放音频和视频文件的功能,可以在应用程序中实现音乐播放、视频播放等功能。使用MediaPlayer,我们可以加载本地文件或者通过网络流来播放音频和视频。 使用MediaPlayer,我们首先需要创建一个MediaPlayer对象,然后设置数据源,可以是本地文件路径或者网络地址。接着,我们可以调用prepare()方法或者prepareAsync()方法来准备MediaPlayer。在准备好之后,我们可以调用start()方法开始播放,调用pause()方法暂停播放,调用seekTo()方法跳转播放位置,调用release()方法释放MediaPlayer等。 MediaPlayer还提供了一些其他的功能,比如设置音量、设置循环播放、设置播放速度等。我们可以使用setVolume()方法设置音量大小,用setLooping()方法设置循环播放,用setPlaybackParams()方法设置播放速度等。 在使用MediaPlayer时,需要注意一些事项。首先,MediaPlayer是一个比较重量级的库,可能会占用较多的内存。其次,需要在使用完MediaPlayer后及时释放资源,防止内存泄漏。另外,还需要在合适的时机处理MediaPlayer的各种状态回调,比如准备完成回调、播放完成回调等。 总的来说,Android Kotlin MediaPlayer 是一个强大的多媒体播放器库,可以帮助我们实现音频和视频播放功能。通过学习和使用MediaPlayer,我们可以为我们的应用程序添加丰富的媒体播放体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值