基于android6.0 mediaplayer框架分析

        Mediaplayer的构造函数里面定义了一个Looper,将该Looper初始化为当前线程使用的Looper,如果为空则初始化为主线程的Looper,再使用该Looper作为参数初始化EventHandler对象。mAppOps保存了AppOpsService的代理对象,AppOpsService功能是检测某些应用是否具有某些权限。

 public MediaPlayer() {

        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        mTimeProvider = new TimeProvider(this);
        mOpenSubtitleSources = new Vector<InputStream>();
        IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
        mAppOps = IAppOpsService.Stub.asInterface(b);

        /* 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));
    }

         接下来调用native_setup的native方法进入native层。 Mediaplayer.java的静态代码块中加载了libmedia_jni.so库,这个操作回去调用JNI层的JNI_OnLoad函数。 JNI_Onload函数作用在与确认JNI的版本1.4,在JNI层注册个种组件。JNI_onload同样也注册了MediaPlayer。

jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("ERROR: GetEnv failed\n");
        goto bail;
    }
    assert(env != NULL);
    ...
     if (register_android_media_MediaPlayer(env) < 0) {
        ALOGE("ERROR: MediaPlayer native registration failed\n");
        goto bail;
    }
    ...


         以native_int和native_setup为例说明对应关系: 1.无参数(),返回值为Void(V)的Java层函数native_init在JNI层对应的函数名为android_media_MediaPlayer_native_init。 2.接收一个Object参数,返回值为Void(V)的Java层函数native_setup在JNI层对应的函数名为android_media_MediaPlayer_native_setup。 

static JNINativeMethod gMethods[] = {
    ...
 {"native_init",         "()V",                              (void *)android_media_MediaPlayer_native_init},
    {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
    ...


        Java层静态代码块使用了native_init,该函数的作用在JNI层将Java层的信息保存在field_t结构体变量中。JNIEnv是一个与线程相关的变量,不同线程的JNIEnv相互独立。由于是获取类的FieldID和MethodID,android_media_MediaPlayer_native_init调用FindClass获得Java层MediaPlaye

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值