Overview
###JNI数据类型
Java数据类型 | JNI数据类型 |
int | jint/jsize |
long | jlong |
byte | jbyte |
string | jstring |
boolean | jboolean |
char | jchar |
float | jfloat |
double | jdouble |
short | jshort |
###Android.mk
Android.mk用来向Android NDK描述C/C++资源文件的,是GNU Makefile的片段。
Android.mk in HelloJni:
1
2
3
4
5
6
7
8
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
- Android.mk必须以LOCAL_PATH的定义开始,用于在开发树中定位源文件。my-dir方法返回当前的目录。
- CLEAR_VARS变量指向一个特定的GNU Makefile,用于阐明除了LOCAL_PATH外的LOCAL_XXX。
- 在Android.mk中必须定义LOCAL_MODULE变量来辨识每个模块。LOCAL_MODULE的名字必须是唯一的,且不包含空格。Build System将自动生成前缀和后缀,例如一个共享库模块的名字是”test”,将会生成”libtest.so”。
- LOCAL_SRC_FILES定义了包括在模块中的一系列C/C++源文件。在这里需要注意的是,不要将头文件和包含文件定义在这里,系统将自动添加依赖。
- BUILD_SHARED_LIBRARY指向了一个GNU Makefile来收集定义在LOCAL_XXX变量中的信息。
###Application.mk
Application.mk用于描述应用所需的native模块。
###JNIEnv
- JNIEnv指向了线程相关的结构,线程相关结构指向了一个指针数组,在指针数组的每个元素都可以指向一个JNI方法。
- JNIEnv用于线程本身的存储,所以不能跨线程传递。
- 在C和C++中的JNIEnv是不同的。
查看/android-ndk-r10/platforms/android-L/arch-arm/usr/include/jni.h
,可以对比在C和C++中对JNIEnv的定义。
1
2
3
4
5
6
7
8
9
10
11
struct _JNIEnv;
struct _JavaVM;
typedef const struct JNINativeInterface* C_JNIEnv;
#if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
#endif
- 在C中:
JNIEnv是struct JNINativeInterface* JNIEnv
,要获取JNINativeInterface中的函数指针,必须对其进行解引用,通过JNIEnv *env来调用JNI方法。例如,(*env)->NewStringUTF(env, "Hello from JNI");
- 在C++中:
JNIEnv是struct _JNIEnv
,调用JNI方法,直接调用即可。例如,nv->NewStringUTF(env, "Hello from JNI");
###输出Log
####引入头文件
在c文件中,加入如下代码。
1
2
3
#define LOG_TAG "jni log"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
__android_log_print
的第一个参数是priority优先级,分为ANDROID_LOG_DEBUG、ANDROID_LOG_ERROR、ANDROID_LOG_INFO等等。第二个参数是tag标签。第三个参数是输出的文本。这就相当于Android中的Log.d(tag, msg)
。
####Android.mk中添加log动态库
在Android.mk文件中,添加LOCAL_LDLIBS += -llog
。
1
2
3
4
5
6
7
8
9
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
添加库的方法是LOCAL_LDLIBS += -lname
,其中的name是动态库的名字,不包含前缀lib和后缀.so。
####添加输出log代码
在c文件中,添加类似LOGE("jni print log”);
的代码,运行即可在logcat中输出你打印的log。