【二】Android MediaPlayer整体架构源码分析 -【Listeners监听事件回调】

本文深入探讨Android 10.0版本的MediaPlayer,关注于事件监听回调的实现,包括setOnPreparedListener等接口的处理。分析了Java层的EventHandler如何通过Handler机制接收和处理来自native层的事件,以及native层如何通过JNIMediaPlayerListener的notify方法进行回调。文章采用倒序方式,从事件回调入手,为后续的prepare流程分析做准备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

承接上一章节分析:【一】Android MediaPlayer整体架构源码分析 -【初始化和创建】
本系列文章分析的安卓源码版本:【Android 10.0 版本】

MediaPlayer设置各种Listener的事件回调处理流程
示例代码如下:

        mMediaPlayer.setOnPreparedListener(mPreparedListener);
        mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
        mMediaPlayer.setOnCompletionListener(mCompletionListener);
        mMediaPlayer.setOnErrorListener(mErrorListener);
        mMediaPlayer.setOnInfoListener(mInfoListener);
        mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
        mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);

本章主要分析java层和native层事件回调通知机制的实现,native层模块之间回调事件通知实现在后续章节中会再次分析到的。
因此,通过前一章节源码分析可知,他们的回调机制是相同的,都是通过Handler机制实现的。【其实现原理可见我另一章节分析(教你手写android底层Handler消息机制实现框架)】

1、以【setOnPreparedListener】为例:

// [android.media.MediaPlayer.java]
   /**
     * Register a callback to be invoked when the media source is ready
     * for playback.
     *
     * @param listener the callback that will be run
     */
    public void setOnPreparedListener(OnPreparedListener listener)
    {
   
        // 只是缓存当前监听事件
        mOnPreparedListener = listener;
    }

通过源码分析,可知每个setListener接口都只是MediaPlayer缓存该监听接口对象,等到回调事件通知时才返回通知应用层。

2、EventHandler的Handler事件接收处理:

// [android.media.MediaPlayer.java]
        @Override
        public void handleMessage(Message msg) {
   
        	// 由上面的分析可知,【mNativeContext】字段缓存的值是native层MediaPlayer对象指针值
            if (mMediaPlayer.mNativeContext == 0) {
   
                Log.w(TAG, "mediaplayer went away with unhandled events");
                return;
            }
            // 所有的底层回调事件都会在此处通过事件类型【不同int值标识】来处理
            // 定义了非常多的事件回调类型,但目前只开放了几个listener事件给应用层使用,
            // 即可以通过设置setListener的方法监听回调事件,其他事件都是此处内部处理的。
            switch(msg.what) {
   
            // prepared状态,即prepare流程执行完成的回调通知事件
            case MEDIA_PREPARED:
                try {
   
                	// 在prepare流程执行完成之后,需要检查是否需要获取底层track集合数据中的
                	// 类型为【TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE】字幕流track
                	// 此处不展开分析
                	// 【通过传递Parcel信息给native层,java层Parcel和native层Parcel转换比较简单,
                	// 就是java层Parcel创建时缓存了对应native层Parcel对象指针值】
                	// 可以参考【andr
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值