android 之 JNI 详解(三)

 3.registerNativeMethods()函数的用途

  应用层级的Java类别透过VM而呼叫到本地函数。一般是仰赖VM去寻找*.so里的本地函数。如果需要连续呼叫很多次,每次都需要寻找一遍,会多花许多时间。此时,组件开发者可以自行将本地函数向VM进行登记。例如,在Android的/system/lib/libmedia_jni.so档案里的代码段如下:

java代码:
  1. //#define LOG_NDEBUG 0

  2. #define LOG_TAG "MediaPlayer-JNI"
  3. static JNINativeMethod gMethods[] = {
  4. {"setDataSource", "(Ljava/lang/String;)V",(void *)android_media_MediaPlayer_setDataSource}, {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V",(void *)android_media_MediaPlayer_setDataSourceFD},
  5. {"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
  6. {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
  7. {"_start", "()V", (void *)android_media_MediaPlayer_start},
  8. {"_stop", "()V", (void *)android_media_MediaPlayer_stop},
  9. {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth},
  10. {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight},
  11. {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo},
  12. {"_pause", "()V", (void *)android_media_MediaPlayer_pause},
  13. {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},
  14. {"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition},
  15. {"getDuration", "()I", (void *)android_media_MediaPlayer_getDuration},
  16. {"_release", "()V", (void *)android_media_MediaPlayer_release},
  17. {"_reset", "()V", (void *)android_media_MediaPlayer_reset},
  18. {"setAudioStreamType","(I)V", (void *)android_media_MediaPlayer_setAudioStreamType},
  19. {"setLooping", "(Z)V", (void *)android_media_MediaPlayer_setLooping},
  20. {"setVolume", "(FF)V", (void *)android_media_MediaPlayer_setVolume},
  21. {"getFrameAt", "(I)Landroid/graphics/Bitmap;",(void *)android_media_MediaPlayer_getFrameAt},
  22. {"native_setup", "(Ljava/lang/Object;)V",(void *)android_media_MediaPlayer_native_setup},
  23. {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
  24. };

  25. static int register_android_media_MediaPlayer(JNIEnv *env){
  26. return AndroidRuntime::registerNativeMethods(env,"android/media/MediaPlayer", gMethods, NELEM(gMethods));
  27. }
复制代码

java代码:
  1. jint JNI_OnLoad(JavaVM* vm, void* reserved){
  2. if (register_android_media_MediaPlayer(env) < 0) {

  3. LOGE("ERROR: MediaPlayer native registration failed ");
  4. goto bail;
  5. }
  6. }

复制代码


        当VM载入libmedia_jni.so档案时,就呼叫JNI_OnLoad()函数。接着,JNI_OnLoad()呼叫 register_android_media_MediaPlayer()函数。此时,就呼叫到 AndroidRuntime::registerNativeMethods()函数,向VM(即AndroidRuntime)登记 gMethods[]表格所含的本地函数了。简而言之,registerNativeMethods()函数的用途有二:

  (1)更有效率去找到函数。
  (2)可在执行期间进行抽换。由于gMethods[]是一个<名称,函数指针>对照表,在程序执行时,可多次呼叫registerNativeMethods()函数来更换本地函数之指针,而达到弹性抽换本地函数之目的。

 

系列之Android 深入研究JNI(三)的帖子链接http://www.eoeandroid.com/thread-87011-1-1.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值