返回介绍

3.1 构造函数

发布于 2024-12-23 21:17:29 字数 1976 浏览 0 评论 0 收藏 0

在 MediaPlayer 的构造函数中调用了 native 的 android_media_MediaPlayer_native_setup 方法:

public MediaPlayer() {
  ...

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

setup 方法中创建了 MediaPlayer,同时也设置了回调函数。其中最后一行的 setMediaPlayer 将 MediaPlayer 的指针保存成一个 Java 对象,之后可以看到 getMediaPlayer 通过同样的方法获取到该对象的指针。

static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)

{
  ALOGV("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);

}

static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
{
  Mutex::Autolock l(sLock);
  /* 由于指针的大小和 long 的大小是一样的,所以这里的 get 和 set 可以将
     MediaPlayer 的指针取出或存入*/
  sp<MediaPlayer> old = (MediaPlayer*)env->GetLongField(thiz, fields.context);
  // 判断 mediaplayer 是否为空指针,如果不是,这 sp 引用计数加 1
  if (player.get()) {
    player->incStrong((void*)setMediaPlayer);
  }
  // 如果之前存过 mediaplayer,检查之前存的是否为空,如果不为空,则引用计数减 1
  if (old != 0) {
    old->decStrong((void*)setMediaPlayer);
  }
  // 将新的 mediaplayer 指针存入 Java 对象中
  env->SetLongField(thiz, fields.context, (jlong)player.get());
  return old;
}

这里解释两点:

1 .由于指针的大小和 long 的大小是一样的,所以可以通过 SetLongField 和 GetLongField 来保存函数指针。

2 .由于 shared_ptr 和 weak_ptr 是 C++11 中才加入的,所以源码中实现了 sp 和 wp 作为智能指针来使用,这里可以看到代码中手动控制了引用计数。

现在一个 mediaplayer 对象就创建好了,其他的 jni 中对应的方法几乎都是调用 mediaplayer 来完成的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文