Android NDK Call Java From C++

I search the Android NDK document and Internet a bit, and could not find anything useful to help me play sound with C++ under the Android NDK. Most of topics are about how to play sound with Java, so I grape an idea that why not call Java from C++. I tried along this way, and finally all those stuff works as I expected before.

 

Implement Java static function

A Sound player class implemented in Java class. In addition to play sound basic feature, I also make it expose a static function that will be called from C++. The reason why I used a static function here is that static function could allow me correctly find the right Java object instance, the one with sound pool initialized well and file loaded ok will be the correct one.

复制代码
public class SoundManager {
    ......
    
    public static void sPlaySound(int sound)
    {
        if ( null != sInstance )
            sInstance.PlaySound(sound);
    }
    
}
复制代码

 

Call Java function from C/C++

复制代码
static JavaVM* g_JavaVM = NULL;
static const char *g_JavaClassName = "com/easygame/SoundManager";

JNIEXPORT jint JNI_OnLoad(JavaVM* jvm, void* reserved)
{
    g_JavaVM = jvm;

    JNIEnv *env = NULL;
    if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
        return -1;

    return JNI_VERSION_1_6;
}

JNIEXPORT void JNI_OnUnload(JavaVM* jvm, void* reserved)
{
    g_JavaVM = NULL;
    JNIEnv *env = NULL;
    if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
        return;
}

void SysPlaySound(int soundId)
{
    if (g_JavaVM == NULL)
        return;

    int status = -1;
    JNIEnv *env = NULL;
    bool isAttached = false;

    status = g_JavaVM->GetEnv((void**) &env, JNI_VERSION_1_6);
    if (status < 0)  
    {
        status = g_JavaVM->AttachCurrentThread(&env, NULL);
        if (status < 0)
            return;
        isAttached = true;
    }

    if ( env != NULL )
    {
        jclass cls = env->FindClass(g_JavaClassName);
        if ( cls != 0 )
        {
            jmethodID mid = env->GetStaticMethodID(cls, "sPlaySound", "(I)V");
            if ( mid != 0 )
                env->CallStaticVoidMethod(cls, mid, soundId);
        }
    }

    if ( isAttached )
        g_JavaVM->DetachCurrentThread();    
}
复制代码

Function JNI_OnLoad and JNI_OnUnload are Android NDK system call back functions, that will allow us to get the current Java virtual machine. We need to get the class static method or object member function  from the Java virtual machine. Now we could call function SysPlaySound as a C/C++ native function.

 

Reference

http://blog.csdn.net/airun_zou/article/details/7110101

http://www.cnblogs.com/luxiaofeng54/archive/2011/08/17/2142000.html

http://qfqf16.blog.163.com/blog/static/128109527201281263955386/

http://blog.chinaunix.net/uid-7448773-id-310170.html

posted @   opencoder  阅读(697)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示