Android MediaPlayer架构 -- 前言小知识点(一)

Android MediaPlayer架构 -- 前言小知识点(一),第1张

概述在Android中可以使用MediaPlayer+SurfaceView来实现一个简单的多媒体播放器。 一 构造函数 java MediaPlayer class 的源码位置:frameworksb

  在AndroID中可以使用MediaPlayer+SurfaceVIEw来实现一个简单的多媒体播放器。

一  构造函数

  java MediaPlayer class 的源码位置:frameworks\base\media\java\androID\media\MediaPlayer.java

  首先看一下其构造函数:

 1     public MediaPlayer() { 2  3         Looper looper; 4         if ((looper = Looper.myLooper()) != null) { 5             mEventHandler = new EventHandler(this,looper); 6         } else if ((looper = Looper.getMainLooper()) !=  7             mEventHandler =  8         } else { 9             mEventHandler = ;10         }11 12         mTimeProvIDer = new TimeProvIDer();13         mOpenSubTitleSources = new Vector<inputStream>();14         IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);15         mAppOps = IAppOpsService.Stub.asInterface(b);16 17         /* Native setup requires a weak reference to our object.18          * It's easIEr to create it here than in C++.19          */20         native_setup(new WeakReference<MediaPlayer>()); // 在实例化MediaPlayer对象时,会调用一个native_setup方法21     }

  在实例化MediaPlayer对象时,会调用一个native_setup方法:

1 private native final voID native_setup(Object mediaplayer_this);

  在JNI代码(frameworks\base\media\jni\androID_media_MediaPlayer.cpp)中可以找到对应的native函数:

 1 static voID 2 androID_media_MediaPlayer_native_setup(jnienv *env,jobject thiz,jobject weak_this){ 4     ALOGV("native_setup" 5     sp<MediaPlayer> mp = new MediaPlayer(); // 实例化一个native MediaPlayer(frameworks\av\media\libmedia\mediaplayer.cpp) 6     if (mp == NulL) { 7         jniThrowException(env,java/lang/RuntimeException",1)">Out of memory 8         return 9     }10 11     // create new Listener and give it to MediaPlayer12     sp<JNIMediaPlayerListener> Listener =  JNIMediaPlayerListener(env,thiz,weak_this);13     mp->setListener(Listener);14 15      Stow our new C++ MediaPlayer in an opaque fIEld in the Java object.16     setMediaPlayer(env,mp);17 }

  在JNI可以看到,sp<MediaPlayer> mp = new MediaPlayer() 这个native MediaPlayer会去和media service进行交互实现真正的播放功能。

 

 二  设置Listener

  在JNI 函数 androID_media_MediaPlayer_native_setup 中有为MediaPlayer设置Listener,目的就是通过callback的方式将player的事件上传至java层,以便用户做出对应的处理

1     2     sp<JNIMediaPlayerListener> Listener = 3     mp->setListener(Listener);

 

  从上面这两行代码可以看到,首先我们实例化一个JNIMediaPlayerListener对象,然后将这个对象传递给了C++ MediaPlayer,在frameworks\av\include\media\mediaplayer.h中定义了Listener的接口形式:

 ref-counted object for callbacks2 class MediaPlayerListener: virtual  RefBase3 4 :5     voID notify(int msg,int ext1,1)">int ext2,1)">const Parcel *obj) = 06 };

  在JNI代码中,JNIMediaPlayerListener class 正是一个MediaPlayerListener的子类,实现了notify函数,其定义如下:

class JNIMediaPlayerListener:  MediaPlayerListener{:    JNIMediaPlayerListener(jnienv* env,jobject weak_thiz);    ~JNIMediaPlayerListener();    const Parcel *obj = NulL);private:    JNIMediaPlayerListener();    jclass      mClass;      Reference to MediaPlayer class    jobject     mObject;     Weak ref to MediaPlayer Java object to call on};

 

   callback事件的传递主要是通过notify函数来完成的,下面看一下这个函数的具体实现过程:

voID JNIMediaPlayerListener::notify(const Parcel *obj){    jnienv *env = AndroIDRuntime::getjnienv();    if (obj && obj->dataSize() > ) {        jobject jParcel = createJavaParcelObject(env);        if (jParcel != NulL) {            Parcel* nativeParcel = parcelForJavaObject(env,jParcel);            nativeParcel->setData(obj->data(),obj->dataSize());            env->CallStaticVoIDMethod(mClass,fIElds.post_event,mObject,msg,ext1,ext2,jParcel);            env->DeleteLocalRef(jParcel);        }    }  {        env->if (env->ExceptionCheck()) {        ALOGW(An exception occurred while notifying an event.);        LOGW_EX(env);        env->ExceptionClear();    }}

msg,obj 携带着事件相关信息及数据;

通过env->CallStaticVoIDMethod()方法去回调MediaPlayer(java)的 fIElds.post_event 方法,并将事件信息及数据传递过去;

fIElds.post_event对应于MediaPlayer的java 方法 postEventFromNative;

fIElds.post_event是在MediaPlayer第一次加载时在androID_media_MediaPlayer_native_init中初始化的;

三  小结

  这一篇介绍的内容很简单,主要是对java层的MediaPlayer, JNI层,及native层的MediaPlayer如何关联起来的有个基本的认识与了解。

  简单两点概述:

java层的MediaPlayer提供了java API供用户调用实现playback功能,但其功能的实现还会串接到JNI层,在JNI层会去实例化一个native MediaPlayer,这个native MediaPlayer会和MediaPlayerService进行交互实现真正的播放功能;设置Listener的目的就是通过回调的方式将来自native的事件进行上传,以便用户在java层做出处理,就这篇而言可以暂时这样理解流程: MediaPlayerService-->native MediaPlayer-->JNI->java MediaPlayer ;

 

总结

以上是内存溢出为你收集整理的Android MediaPlayer架构 -- 前言知识点(一)全部内容,希望文章能够帮你解决Android MediaPlayer架构 -- 前言小知识点(一)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1119318.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存