在Android中如果要编写JNI。首先要在本地编写对应的native方法:代码如下:
package com.android.jni.center;
public class NewJni {
public native String getStringFromC();
public native void sendData(String data);
public native void sendIntData(int data);
public native int getAge();
}
编写完成后,需要生成对应的头文件。生成方式如下:
1,先用javac命令生成对应的class文件:
E:\WorkSpace\AndroidJNI\app\src\main\java>javac com/android/jni/center/NewJni.java
生成对应的class文件之后,使用javah生辰对应的头文件:
E:\WorkSpace\AndroidJNI\app\src\main\java>javah com.android.jni.center.NewJni
生成对应的头文件之后,将对应的.h文件添加到对应的目录下。在项目的根目录中增加jni对应的目录,然后在jni文件中,增加对应的c文件
如果不添加对应的.h文件会出现如下异常:
E:\WorkSpace\AndroidJNI\jni>ndk-build
[arm64-v8a] Compile : JniC <= JniC.c
E:/WorkSpace/AndroidJNI/jni/JniC.c:4:9: fatal error: 'com_android_jni_center_NewJni.h' file not found
#include<com_android_jni_center_NewJni.h>
完成之后,进入到jni对应的目录。然后输入ndk-build进行编译,然后会自动生成对应的.so文件。
常见异常总结:
E:/WorkSpace/AndroidJNI/jni/JniC.c:4:9: fatal error: 'com_android_jni_center_NewJni.h' file not found
#include<com_android_jni_center_NewJni.h>
上述错误是由于生成的.h头文件,没有和.c文件放到同一个目录,将两个文件放入同一个目录,重新执行ndk-build即可
E:/WorkSpace/AndroidJNI/jni/JniC.c:28:12: error: parameter name omitted
(JNIEnv *, jobject){
上述错误是由于 javah生成的头文件,生成的方法中,只有参数类型,没有变量名称,类似java中的 public void say(String),没有变量名称。只要增加上对应的变量名称即可。修改成类似如下:
E:/WorkSpace/AndroidJNI/jni/JniC.c:28:12: error: parameter name omitted
(JNIEnv * env, jobject obj){
E:/WorkSpace/AndroidJNI/jni/JniC.c:34:25: error: use of undeclared identifier 'env'
jstring jstr2 = (*env) -> NewStringUTF(env, cstr);
上述异常,是由于找不到env这个变量,确认一下是否有这个变量即可,一般这个变量都是方法参数中的,代表c环境的上下文对象
E:/WorkSpace/AndroidJNI/jni/JniC.c:35:3: warning: control reaches end of non-void function [-Wreturn-type]
}
上述异常,是由于对应的c文件中,35行的函数,声明有一个返回值,但是一直到函数结尾也没有return返回值,说白了就是,函数你没有返回值
E:/WorkSpace/AndroidJNI/jni/JniC.c:44:10: error: unexpected type name 'jstring': expected expression
printf(jstring);
E:/WorkSpace/AndroidJNI/jni/JniC.c:54:8: error: unexpected type name 'jint': expected expression
printf(jint);
上述异常,是由于c中调用了打印。但是打印的内容传递的不是变量 而是类型导致的,类似于java中的 System.out.print(int) 这种写法,所以你只要将jint,jstring改成对应的变量名即可
E:/WorkSpace/AndroidJNI/jni/JniC.c:44:10: error: format string is not a string literal (potentially insecure)
[-Werror,-Wformat-security]
printf(str);