android jni

在 Java 程序中调用 native code;在 native code 中嵌入 Java 虚拟机调用 Java 的代码

注意:
(1) 从Java 环境到 native code 的上下文切换耗时、低效。
(2) JNI 编程,如果操作不当,可能引起 Java 虚拟机的崩溃。
(3) JNI 编程,如果操作不当,可能引起内存泄漏。

c++调用java
返回值 方法名 (参数)
{
JniMethodInfo_ methodInfo;
    if (!JniHelper::getStaticMethodInfo(methodInfo, java中方法所在类的路径, "方法名", "(参数)返回值")) {
       return;
    }
   methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
   methodInfo.env->DeleteLocalRef(methodInfo.classID);
}

说明:
typedef struct JniMethodInfo_
{
   JNIEnv *    env;
   jclass      classID;
   jmethodID   methodID;
} JniMethodInfo;


说明:JNIEnv * 
在Android中,当Java文件被编译成dex文件之后,会由类加载器加载到Dalvik VM(DVM)中,由DVM来进行解释,翻译成机器语言之后,才能由机器来运行。
而对于C/C++来说,其源代码经由Android提供的NDK工具包,可以编译成可执行动态库(即.so文件),之后,Java和C++之间就可以进行通讯了。
那么,在这里,可以想像,Java的Dex字节码和C/C++的so库肯定是同时运行在一个DVM之中,它们是共同使用一个进程空间的,否则,它们怎么彼此沟通呢?
所以在这里,一个关键的中间区域就是Dalvik VM。而对于C/C++,当它们也被加载进DVM之后,由C/C++实现的函数方法等都会被加载 在DVM中的函数表中。
如果想要在C/C++中调 用函数,它们必须要有个东西能够让其访问到这个虚拟机中的函数表。
而这个东西就是JNIEnv *。  对Java虚拟环境的一个引用,在Android中,就是指Dalvik VM;

JniHelper::getStaticMethodInfo(methodInfo, java中方法所在类的路径, "方法名", "(参数)返回值")) java方法为静态
JniHelper::getMethodInfo(methodInfo, java中方法所在类的路径, "方法名", "(参数)返回值")) java方法不为静态
返回值为false表示在相应的java类中没有找到方法
例:JniHelper::getStaticMethodInfo(methodInfo, com/example/text/class1, "function", "()V" -------- C++      说明:com/example/text为包名、class1为类名 function为方法名 返回值为空参数为空
public static void function()  -------------------------------------------------------------------  JAVA

参数 与 java中的参数简写!! 对应关系
boolean Z
byte B
char C
short S
int I
long J
float F
double D
void V
Object Ljava/lang/String; L用/分割类的完整路径
Array [Ljava/lang/String; [签名 [I

如果函数有多个参数,直接把简写并列即可。注意Object与Array型参数简写结尾的分号,示例:
IIII //4个int型参数的函数
ILjava/lang/String;I //整形,string类型,整形组合 (int x, String a, int y)

返回值 = methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, 参数);
   methodInfo.env->DeleteLocalRef(methodInfo.classID);

    CallStaticVoidMethod  ----- void
    CallVoidMethod ------------ void    以函数返回类型的不同,对应不同的函数名

返回值 与 java中的返回值 对应关系
Void void
Object jobject
Boolean jboolean
Byte jbyte
Char jchar
Short jshort
Int jint
Long jlong
Float jfloat
Double jdouble

c++参数 与 java中类型 对应关系
boolean jboolean
byte jbyte
char jchar
short jshort
int jint
long jlong
float jfloat
double jdouble
Object jobject
Class jclass
String jstring
Object[] jobjectArray
boolean[] jbooleanArray
byte[] jbyteArray
char[] jcharArray
short[] jshortArray
int[] jintArray
long[] jlongArray
float[] jfloatArray
double[] jdoubleArray

    例如:
    const char* MultiplayerGame::getDeviceName(const char* pBuffer)
    {
        JniMethodInfo t;
      if (!JniHelper::getStaticMethodInfo(t, com/example/text/className, "function", "(Ljava/lang/String;)Ljava/lang/String;")) {
            return "error";
        }

        jstring stringArg1;
            if (!pBuffer) {
                stringArg1 = methodInfo.env->NewStringUTF("");
            } else {
                stringArg1 = methodInfo.env->NewStringUTF(pBuffer);
            }

        jstring text = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID, stringArg1);

        t.env->DeleteLocalRef(stringArg1);
        t.env->DeleteLocalRef(t.classID);

        return t.env->GetStringUTFChars(text, 0);
    }

    实际上我们最常用的参数类型,主要是内建的数据类型、string字符串类型。数据类型可以直接转为j类型,但是string类型需要做如下处理:
jstring jmsg = minfo.env->NewStringUTF(pBuffer); -------------- c++ 中的 const char* 转化为 java 中的 jstring
std::string strValue = JniHelper::jstring2string(text);-------- java 中的 jstring 转化为 c++ 中的 std::string
char* pValue = t.env->GetStringUTFChars(text, 0)--------------- java 中的 jstring 转化为 c++ 中的 char*

释放内存
methodInfo.env->DeleteLocalRef(stringArg1);

java调用c++
c++ 中
extern "C" {
JNIEXPORT 返回值类型 JNICALL
   Java_com_example_text_className_方法名(JNIEnv* env, jobject thiz, 参数);
}
JNIEXPORT 返回值类型 JNICALL
   Java_com_example_text_className_方法名(JNIEnv* env, jobject thiz, 参数){
   return 返回值;
   }

java com.example.text 包中的 className 类中
public 返回值类型 方法名 (参数){renturn 返回值}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值