jni函数绑定有两种方法,一种是静态绑定,一种是注册方式。当前介绍静态绑定
1 构造Java类
package cn.search;
import java.io.File;
import android.os.Environment;
import android.util.Log;
public class PoiResolver{
public native String GetDistrictName(String storagePath, double longtitude, double latitude);
public native String GetPOIName(String storagePath, double longtitude, double latitude);
public native String GetRoadName(String storagePath, double longtitude, double latitude);
}
说明:native修饰符告诉Java编译器这是一个绑定到JNI的函数原型
2 利用javah生成头文件
本项目使用Eclipse创建Android工程,进入工程的顶级目录,PoiResolver类文件保存在src/cn/search目录下
在顶级目录下执行如下在指令:javah -o jni/cn_search.h -classpath src/ -jni cn.search.PoiResolver
-o:指定输出的文件名称,将在jni下创建cn_search.h文件,然后将头文件内容写入该文件
-classpath:指定需要生成h文件的类所在的包所在的位置(包cn.search在src/目录下)
-jni:指定需要生成h文件的类,这个时候必须指定详细的包名+类名
可以使用-d参数,但是不能够再使用-o参数,没有指定文件名的情况下,默认名称为包名+类名.h
注意
在jni的.c文件中调用env,必须这样调用:return (*env)->NewStringUTF(env, "Hello !");
在jni的.cpp文件中调用env,必须这样调用:return env->NewStringUTF("Hello !");
3 编写Application.mk
该文件定义了哪种平台的so文件,进入jni文件夹,创建Application.mk文件,写入内容:
APP_ABI := all
将生成四种平台的so文件:armeabi-v7a armeabi x86 mips
使用ndk-build指令生成so文件时候,可以通过传递参数,例子如下:ndk-build APP_ABI = armeabi-v7a ,单独生成某一个平台so文件,当然也可以直接在文件中修改
4 创建Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_MODULE := libsearch
LOCAL_SRC_FILES := cn_search_poiresolver.cpp
include $(BUILD_SHARED_LIBRARY)
注意
对于动态注册的方式,函数的参数列表前面两个参数是固定的:
static void SetSystemParameter(int paramType, int paramValue)
{
}
目前一段时间没有写jni接口,因此例如上面的函数定义是错误的,在调用该函数的时候,会发现传递进来的参数都是错误的,是一个非常庞大的数据,因此怀疑其实传递进来的其实是一个指针值!!
正确
static void SetSystemParameter(JNIEnv* env, jobject obj, jint paramType, jint paramValue)
{
}