JNI例子

实例见https://blog.csdn.net/u010349644/article/details/80816701

这个是android源代码(android R)

frameworks/base/media/java/android/media/MediaRecorder.java
public class MediaRecorder implements AudioRouting,
                                      AudioRecordingMonitor,
                                      AudioRecordingMonitorClient,
                                      MicrophoneDirection
{
     static {
         System.loadLibrary("media_jni");
         native_init();
     }
  @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
      private static native final void native_init();
  
      @UnsupportedAppUsage
      private native final void native_setup(Object mediarecorder_this,
              String clientName, String opPackageName) throws IllegalStateException;

 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
      private native final void native_finalize();
  
      @UnsupportedAppUsage
      private native void setParameter(String nameValuePair);

 public int getPortId() {
          if (mNativeContext == 0) {
              return 0;
          }
          return native_getPortId();
      }
  
      private native int native_getPortId();

   public void setAudioSamplingRate(int samplingRate) {
         if (samplingRate <= 0) {
             throw new IllegalArgumentException("Audio sampling rate is not positive");
         }
         setParameter("audio-param-sampling-rate=" + samplingRate);
     }
--------------------------------------------------

frameworks/base/media/jni/android_media_MediaRecorder.cpp

// ref-counted object for callbacks
class JNIMediaRecorderListener: public MediaRecorderListener
{
public:
    JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
    ~JNIMediaRecorderListener();
    void notify(int msg, int ext1, int ext2);
private:
    JNIMediaRecorderListener();
    jclass      mClass;     // Reference to MediaRecorder class
    jobject     mObject;    // Weak ref to MediaRecorder Java object to call on
};

JNIMediaRecorderListener::JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
{

    // Hold onto the MediaRecorder class for use in calling the static method
    // that posts events to the application thread.
    jclass clazz = env->GetObjectClass(thiz);
    if (clazz == NULL) {
        ALOGE("Can't find android/media/MediaRecorder");
        jniThrowException(env, "java/lang/Exception", NULL);
        return;
     }
     mClass = (jclass)env->NewGlobalRef(clazz);
 
     // We use a weak reference so the MediaRecorder object can be garbage collected.
     // The reference is only used as a proxy for callbacks.
     mObject  = env->NewGlobalRef(weak_thiz);
 }
 
 JNIMediaRecorderListener::~JNIMediaRecorderListener()
 {
     // remove global references
     JNIEnv *env = AndroidRuntime::getJNIEnv();
     env->DeleteGlobalRef(mObject);
     env->DeleteGlobalRef(mClass);
 }
 
 void JNIMediaRecorderListener::notify(int msg, int ext1, int ext2)
 {
     ALOGV("JNIMediaRecorderListener::notify");
 
     JNIEnv *env = AndroidRuntime::getJNIEnv();
     env->CallStaticVoidMethod(mClass, fields.post_event, mObject, msg, ext1, ext2, NULL);
 }
 

 static void
 android_media_MediaRecorder_setParameter(JNIEnv *env, jobject thiz, jstring params)
 {
     ALOGV("setParameter()");
     if (params == NULL)
     {
         ALOGE("Invalid or empty params string.  This parameter will be ignored.");
         return;
     }
 
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
 
     const char* params8 = env->GetStringUTFChars(params, NULL);
     if (params8 == NULL)
     {
         ALOGE("Failed to covert jstring to String8.  This parameter will be ignored.");
         return;
     }
 
     process_media_recorder_call(env, mr->setParameters(String8(params8)), "java/lang/RuntimeException", "setParameter failed.");
     env->ReleaseStringUTFChars(params,params8);
 }
 
 
 static void
 android_media_MediaRecorder_start(JNIEnv *env, jobject thiz)
 {
     ALOGV("start");
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
     process_media_recorder_call(env, mr->start(), "java/lang/RuntimeException", "start failed.");
 }
 
 static void
 android_media_MediaRecorder_stop(JNIEnv *env, jobject thiz)
 {
     ALOGV("stop");
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
     process_media_recorder_call(env, mr->stop(), "java/lang/RuntimeException", "stop failed.");
 }
 
 static void
 android_media_MediaRecorder_pause(JNIEnv *env, jobject thiz)
 {
     ALOGV("pause");
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
     process_media_recorder_call(env, mr->pause(), "java/lang/RuntimeException", "pause failed.");
 }
 
 static void
 android_media_MediaRecorder_resume(JNIEnv *env, jobject thiz)
 {
     ALOGV("resume");
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
     process_media_recorder_call(env, mr->resume(), "java/lang/RuntimeException", "resume failed.");
 }
 
 static void
 android_media_MediaRecorder_native_reset(JNIEnv *env, jobject thiz)
 {
     ALOGV("native_reset");
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
     process_media_recorder_call(env, mr->reset(), "java/lang/RuntimeException", "native_reset failed.");
 }
 
 static void
 android_media_MediaRecorder_release(JNIEnv *env, jobject thiz)
 {
     ALOGV("release");
     sp<MediaRecorder> mr = setMediaRecorder(env, thiz, 0);
     if (mr != NULL) {
         mr->setListener(NULL);
         mr->release();
     }
 }
 
 // This function gets some field IDs, which in turn causes class initialization.
 // It is called from a static block in MediaRecorder, which won't run until the
 // first time an instance of this class is used.
 static void
 android_media_MediaRecorder_native_init(JNIEnv *env)
 {
     jclass clazz;
 
     clazz = env->FindClass("android/media/MediaRecorder");
     if (clazz == NULL) {
         return;
     }
 
     fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
     if (fields.context == NULL) {
         return;
     }
 
     fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
     if (fields.surface == NULL) {
         return;
     }
 
     jclass surface = env->FindClass("android/view/Surface");
     if (surface == NULL) {
         return;
     }
 
     fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
                                                "(Ljava/lang/Object;IIILjava/lang/Object;)V");
     if (fields.post_event == NULL) {
         return;
     }
 
     clazz = env->FindClass("java/util/ArrayList");
     if (clazz == NULL) {
         return;
     }
     gArrayListFields.add = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z");
     gArrayListFields.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
 }
 
 
 static void
 android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
                                          jstring packageName, jstring opPackageName)
 {
     ALOGV("setup");
 
     ScopedUtfChars opPackageNameStr(env, opPackageName);
 
     sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str()));
     if (mr == NULL) {
         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
         return;
     }
     if (mr->initCheck() != NO_ERROR) {
         jniThrowException(env, "java/lang/RuntimeException", "Unable to initialize media recorder");
         return;
     }
 
     // create new listener and give it to MediaRecorder
     sp<JNIMediaRecorderListener> listener = new JNIMediaRecorderListener(env, thiz, weak_this);
     mr->setListener(listener);
 
     // Convert client name jstring to String16
     const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
         env->GetStringChars(packageName, NULL));
     jsize rawClientNameLen = env->GetStringLength(packageName);
     String16 clientName(rawClientName, rawClientNameLen);
     env->ReleaseStringChars(packageName,
                             reinterpret_cast<const jchar*>(rawClientName));
 
     // pass client package name for permissions tracking
     mr->setClientName(clientName);
 
     setMediaRecorder(env, thiz, mr);
 }
 
 static void
 android_media_MediaRecorder_native_finalize(JNIEnv *env, jobject thiz)
 {
     ALOGV("finalize");
     android_media_MediaRecorder_release(env, thiz);
 }
 
 
 static void
 android_media_MediaRecorder_enableDeviceCallback(JNIEnv *env, jobject thiz, jboolean enabled)
 {
     ALOGV("android_media_MediaRecorder_enableDeviceCallback %d", enabled);
 
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
 
     process_media_recorder_call(env, mr->enableAudioDeviceCallback(enabled),
             "java/lang/RuntimeException", "enableDeviceCallback failed.");
 }
 

 
 static jint android_media_MediaRecord_getPortId(JNIEnv *env,  jobject thiz) {
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
     if (mr == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return (jint)AUDIO_PORT_HANDLE_NONE;
     }
 
     audio_port_handle_t portId;
     process_media_recorder_call(env, mr->getPortId(&portId),
                                 "java/lang/RuntimeException", "getPortId failed.");
     return (jint)portId;
 }
 
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
     {"setParameter",         "(Ljava/lang/String;)V",           (void *)android_media_MediaRecorder_setParameter},
     {"start",                "()V",                             (void *)android_media_MediaRecorder_start},
     {"stop",                 "()V",                             (void *)android_media_MediaRecorder_stop},
     {"pause",                "()V",                             (void *)android_media_MediaRecorder_pause},
     {"resume",               "()V",                             (void *)android_media_MediaRecorder_resume},
     {"native_reset",         "()V",                             (void *)android_media_MediaRecorder_native_reset},
     {"release",              "()V",                             (void *)android_media_MediaRecorder_release},
     {"native_init",          "()V",                             (void *)android_media_MediaRecorder_native_init},
     {"native_setup",         "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V",
                                                                 (void *)android_media_MediaRecorder_native_setup},
     {"native_finalize",      "()V",                             (void *)android_media_MediaRecorder_native_finalize},
     {"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
 
 };
 
 // This function only registers the native methods, and is called from
 // JNI_OnLoad in android_media_MediaPlayer.cpp
 int register_android_media_MediaRecorder(JNIEnv *env)
 {
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaRecorder", gMethods, NELEM(gMethods));
 }
 

/frameworks/base/media/jni/android_media_MediaPlayer.cpp
extern int register_android_media_MediaRecorder(JNIEnv *env);

  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_MediaRecorder(env) < 0) {
          ALOGE("ERROR: MediaRecorder native registration failed\n");
          goto bail;
      }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值