步骤
1. java层静态代码块:public static native String fun(String str);
2. 生成包名.类名.h头文件:javah -classpath bin/class; android.jar -d jni 包名.类名
-classpath:把java代码编译成的.class的目录
-d:输出目录
3. 创建.cpp文件:复制头文件中的函数名再实现函数
4. mk文件:编译脚本
LOCAL_MODULE := xxx // so名字
LOCAL_SRC_FILES := xxx // c代码文件
5. 编译:ndk-build
6. 导入so:System.loadLibrary("xxx");
7. 调用fun方法
java数据类型与native数据类型映射
除了void对应void,其它的都是在原类型上加j,比如int对应jint。
编写native
1. Java类型转native类型:在基本类型上加j
2. 函数指针:JNIEnv *env
3. 获取java层传过来的参数
a. 整型
b. 字符串转换
// 生成指针
const char *p = (*env)->GetStringUTFChars(env, str, NULL); // 默认值NULL
// 释放指针
(*env)->ReleaseStringUTFChars(env, str, p);
c. 数组拷贝
public static native int[] fun(int[] arr);
jint array[5];
// 数组复制
(*env)->GetIntArrayRegion(env, 0, 5, arr);// 从0到5
(*env)->SetIntArrayRegion(env, 0, 5, arr);
d. 数组指针
// 生成数组指针
jint *p = (*env)->GetIntArrayElements(env, arr, NULL);
// 数组长度
jsize len = GetArrayLength(env, arr);
(*env)->ReleaseStringUTFChars(env,arr,p);
4. 返回值给java层
a. 基本类型直接return数据
b. 数组需要NewxxxArray和SetxxxArrayRegion创建和赋值再return
c. 类或结构体:搜索类FindClass,获取构造函数GetMethodID,创建实例NewObject,获取成员属性GetFieldID,设置属性SetXXXField,最后return