jni开发-GetMethodID与CallObjectMethod的坑

在java层中声明一个方法用于创建一个audiotrack,在C层中调用这个方法并获取audiotrack对象。

先看下面的代码:SuPlayer.java

public AudioTrack createAudioTrack(int sampleRateInHz, int nb_channels) {
    //固定格式的音频码流
    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    //声道布局
    int channelConfig;
    if (nb_channels == 1) {
        channelConfig = android.media.AudioFormat.CHANNEL_OUT_MONO;
    } else if (nb_channels == 2) {
        channelConfig = android.media.AudioFormat.CHANNEL_OUT_STEREO;
    } else {
        channelConfig = android.media.AudioFormat.CHANNEL_OUT_STEREO;
    }

    int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);

    AudioTrack audioTrack = new AudioTrack(
            AudioManager.STREAM_MUSIC,
            sampleRateInHz, channelConfig,
            audioFormat,
            bufferSizeInBytes, AudioTrack.MODE_STREAM);
    //播放
    //audioTrack.play();
    //写入PCM
    //audioTrack.write(audioData, offsetInBytes, sizeInBytes);
    return audioTrack;
}

//只播放视频
public static native int playVideo(String url, Surface surface);

//音视频同步播放
public native void playSyncVideo(String url, Surface surface);

C层实现:

JNIEXPORT void
JNICALL Java_com_eebbk_suplayer_SuPlayer_playSyncVideo(JNIEnv *env, jobject thiz, jstring inputPath_, jobject surface) {
    int i = 1;
    //JNI begin------------------
    jclass player_class = env->GetObjectClass(jthiz);//获取当前类的class
    //获取methodID,调java层的createAudioTrack函数,返回值是(II)Landroid/media/AudioTrack;
    //详细参考:http://hubeihuyanwei.blog.163.com/blog/static/28205284201282911925396/
    jmethodID create_audio_track_mid = env->GetMethodID(player_class, "createAudioTrack",
                                                        "(II)Landroid/media/AudioTrack;");
    if (create_audio_track_mid == NULL) {
        LOGE("%s", "createAudioTrack 方法没找到!\n");
    }
    //获取audio_track对象,传入methodid、java层中对应方法的形参
    jobject audio_track = env->CallObjectMethod(jthiz, create_audio_track_mid, i, i);
    //调用AudioTrack.play方法
    jclass audio_track_class = env->GetObjectClass(audio_track);
    jmethodID audio_track_play_mid = env->GetMethodID(audio_track_class, "play", "()V");
    env->CallVoidMethod(audio_track, audio_track_play_mid);
    //AudioTrack.write
    jmethodID audio_track_write_mid = env->GetMethodID(audio_track_class, "write",  "([BII)I");
    LOGE("%s", "44444");
    //JNI end------------------
}

就这么简单的调用顺序,为什么要写这篇笔记呢???因为在写这个的时候,把SuPlayer.java中public AudioTrack createAudioTrack(int sampleRateInHz, int nb_channels)这个方法写成了静态方法public static AudioTrack createAudioTrack(int sampleRateInHz, int nb_channels)。导致排查的时候一直以为env->GetMethodID()这个函数写的有问题。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章