android JNI 系列 一

来源:互联网 发布:sql server 安装 编辑:程序博客网 时间:2024/05/22 03:22

本文介绍一下用ndk实现jni的方式。

 静态注册函数

1. 下载linux版的ndk,windows配环境好像有点麻烦,所以就不说了

 

2. 配置NDK环境变量:

a.sudo gedit ~/.bashrc

b.在文件中输入如下的内容:

NDKROOT=/home/username/android/ndk/android-ndk-r8
export NDKROOT;

c.更新一下环境配置:source ~/.bashrc

 

4.创建一个android项目,例子如下:

 

5. 编译该android工程,目的是为了在bin下面生成class文件

6. 在项目根目录输入: javah -classpath <bin下面类包的根目录> -d jni org.eshock.jnitest.JNITest, 此时会在项目根目的jni文件夹下生成一个org_eshock_jnitest_JNITest.h 文件,

内容如下:

7.在jni目录手机创建相应的cpp文件,代码如下:

 

8. 在jni文件夹下编写Android.mk文件,内容如下:

9. 把整个项目文件夹拷到ndk/samples/下面。

10. 进入到ndk/samples/<projectname>/ 下,然后输入 $NDKROOT/ndk-build <module name>

11. 它会在ndk/samples/<projectname>/下生成obj/local/armeabi/lib***.so 

 

动态注册函数

加Java定义如下:

class Test{private native int add(int a, int b);}

 

1. JNI在加载时,会调用JNI_OnLoad,而卸载时会调用JNI_UnLoad,所以我们可以在JNI_OnLoad里面注册我们的native函数

jint JNI_OnLoad(JavaVM* vm, void* reserved){JNIEnv* env = NULL;jint result = -1;if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK){LOGE("ERROR:GetEnv failed\n");goto bail;}assert(env != NULL);if (register_native_function(env) < 0) {LOGE("ERROR: Boa Server native registration failed");goto bail;}result = JNI_VERSION_1_4;bail:return result;}

2. 自已定义register_native_function函数

int register_ckt_BehaviorManager(JNIEnv *env){return jniRegisterNativeMethods(env, "com/lht/Test",gMethods, NELEM(gMethods));}

jniRegisterNativeMethods是JNI注册函数,"com/lht/Test"是对应的Java类,gMethods是一个Java和Native方法对应的数据结构。

typedef struct {    const char* name; //Java中申明的Native函数名称    const char* signature; //函数描述,这个具体的写法在以后的篇章里会定义    void*       fnPtr; //Natvie函数指针} JNINativeMethod;

3. 定义JNINativeMethod

static JNINativeMethod gMethods[] = {{"add", "(II)I", (void*)com_lht_Test_add},};

4. 实现add函数:

jint com_lht_Test_add(JNIEnv *env, jobject clazz, jint a, jint b){ return (a + b); }

5.Makefile定义

以下方式是用NDK编译的方式

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)# 添加代码文件LOCAL_SRC_FILES:= \    com_lht_Test.cpp# 添加头文件LOCAL_C_INCLUDES += \$(JNI_H_INCLUDE) \# 添加相关库文件LOCAL_SHARED_LIBRARIES := \libur \libcutils \# 生成的目标so名称LOCAL_MODULE := libTest_jniLOCAL_MODULE_TAGS := optionalinclude $(BUILD_SHARED_LIBRARY)


 

NDK_stack

追踪出问题代码的行数

源码:

#include "com_example_testjni_MainActivity.h"JNIEXPORT jint JNICALL Java_com_example_testjni_MainActivity_add(JNIEnv *env, jobject c, jint a, jint b){    char *str = "abc\n";    str[4] = 8;    return (a + b);}


F/libc    (14337): Fatal signal 11 (SIGSEGV) at 0x752cb0fc (code=2), thread 14337 (example.testjni)I/DEBUG   (  263): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***I/DEBUG   (  263): Build fingerprint: 'eng/debug,test-keys'I/DEBUG   (  263): Revision: '115'I/DEBUG   (  263): pid: 14337, tid: 14337, name: example.testjni  >>> com.example.testjni <<<I/DEBUG   (  263): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 752cb0fcI/DEBUG   (  263):     r0 00000008  r1 752cb0f8  r2 00000003  r3 00000005I/DEBUG   (  263):     r4 6d8b9438  r5 415e68f8  r6 00000004  r7 41535ca0I/DEBUG   (  263):     r8 be9b42b8  r9 41535c98  sl 415e6908  fp be9b42ccI/DEBUG   (  263):     ip 752c9bb9  sp be9b42b8  lr 41607450  pc 752c9bbe  cpsr 000b0030I/DEBUG   (  263):     d0  6d6178652f6d6f63  d1  747365742f656c70I/DEBUG   (  263):     d2  6e69614d2f696e6a  d3  7974697669746341I/DEBUG   (  263):     d4  0000000000000000  d5  0000000000000000I/DEBUG   (  263):     d6  0000000000000000  d7  4140000000000000I/DEBUG   (  263):     d8  0000000000000000  d9  0000000000000000I/DEBUG   (  263):     d10 0000000000000000  d11 0000000000000000I/DEBUG   (  263):     d12 0000000000000000  d13 0000000000000000I/DEBUG   (  263):     d14 0000000000000000  d15 0000000000000000I/DEBUG   (  263):     d16 41ad6c7041abbf68  d17 41ac50d041ad1770I/DEBUG   (  263):     d18 000000010000012e  d19 000000010000016dI/DEBUG   (  263):     d20 00000001000012dc  d21 00000001000014ebI/DEBUG   (  263):     d22 00000001000014fa  d23 00000001000014fcI/DEBUG   (  263):     d24 0000000000000000  d25 0000000000000000I/DEBUG   (  263):     d26 0000000000000000  d27 8080808080808080I/DEBUG   (  263):     d28 0100010001000100  d29 0100010001000100I/DEBUG   (  263):     d30 8080808080808080  d31 8080808080808080I/DEBUG   (  263):     scr 60000010I/DEBUG   (  263): I/DEBUG   (  263): backtrace:I/DEBUG   (  263):     #00  pc 00000bbe  /data/app-lib/com.example.testjni-1/libjnitest.so (Java_com_example_testjni_MainActivity_add+5)I/DEBUG   (  263):     #01  pc 0002044c  /system/lib/libdvm.so (dvmPlatformInvoke+112)I/DEBUG   (  263):     #02  pc 000512b3  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)I/DEBUG   (  263):     #03  pc 0003b83d  /system/lib/libdvm.so (dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+8)I/DEBUG   (  263):     #04  pc 00052cb5  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+184)I/DEBUG   (  263):     #05  pc 000298e0  /system/lib/libdvm.soI/DEBUG   (  263):     #06  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)I/DEBUG   (  263):     #07  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)I/DEBUG   (  263):     #08  pc 00063a11  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+392)I/DEBUG   (  263):     #09  pc 0006b873  /system/lib/libdvm.soI/DEBUG   (  263):     #10  pc 000298e0  /system/lib/libdvm.soI/DEBUG   (  263):     #11  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)I/DEBUG   (  263):     #12  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)I/DEBUG   (  263):     #13  pc 0006372d  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)I/DEBUG   (  263):     #14  pc 0004ce9b  /system/lib/libdvm.soI/DEBUG   (  263):     #15  pc 0003fe05  /system/lib/libdvm.soI/DEBUG   (  263):     #16  pc 0004fb7f  /system/lib/libandroid_runtime.soI/DEBUG   (  263):     #17  pc 000508c5  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+388)I/DEBUG   (  263):     #18  pc 0000105b  /system/bin/app_processI/DEBUG   (  263):     #19  pc 0000e593  /system/lib/libc.so (__libc_init+50)I/DEBUG   (  263):     #20  pc 00000d7c  /system/bin/app_processI/DEBUG   (  263): I/DEBUG   (  263): stack:I/DEBUG   (  263):          be9b4278  be9b42e0  [stack]I/DEBUG   (  263):          be9b427c  4009d49f  /system/lib/libc.so (dlfree+50)I/DEBUG   (  263):          be9b4280  400d6000  /system/lib/libc.soI/DEBUG   (  263):          be9b4284  c31b3810  I/DEBUG   (  263):          be9b4288  752e4840  I/DEBUG   (  263):          be9b428c  00000000  I/DEBUG   (  263):          be9b4290  00000000  I/DEBUG   (  263):          be9b4294  00000000  I/DEBUG   (  263):          be9b4298  00000000  I/DEBUG   (  263):          be9b429c  c31b3810  I/DEBUG   (  263):          be9b42a0  41aab530  /dev/ashmem/dalvik-heap (deleted)I/DEBUG   (  263):          be9b42a4  415e68f8  [heap]I/DEBUG   (  263):          be9b42a8  415e69a0  [heap]I/DEBUG   (  263):          be9b42ac  416a4c38  /system/lib/libdvm.soI/DEBUG   (  263):          be9b42b0  df0027ad  I/DEBUG   (  263):          be9b42b4  00000000  I/DEBUG   (  263):     #00  be9b42b8  41535c94  I/DEBUG   (  263):          ........  ........I/DEBUG   (  263):     #01  be9b42b8  41535c94  I/DEBUG   (  263):          be9b42bc  00000001  I/DEBUG   (  263):          be9b42c0  00000000  I/DEBUG   (  263):          be9b42c4  41aab530  /dev/ashmem/dalvik-heap (deleted)I/DEBUG   (  263):          be9b42c8  41aa3fa4  /dev/ashmem/dalvik-heap (deleted)I/DEBUG   (  263):          be9b42cc  416382b7  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+402)I/DEBUG   (  263):     #02  be9b42d0  41535c94  I/DEBUG   (  263):          be9b42d4  7528331e  /data/dalvik-cache/data@app@com.example.testjni-1.apk@classes.dexI/DEBUG   (  263):          be9b42d8  752c9bb9  /data/app-lib/com.example.testjni-1/libjnitest.so (Java_com_example_testjni_MainActivity_add)I/DEBUG   (  263):          be9b42dc  415e6908  [heap]I/DEBUG   (  263):          be9b42e0  752e5b68  I/DEBUG   (  263):          be9b42e4  752e5b70  I/DEBUG   (  263):          be9b42e8  00000000  I/DEBUG   (  263):          be9b42ec  00000000  I/DEBUG   (  263):          be9b42f0  7179824c  I/DEBUG   (  263):          be9b42f4  400da394  I/DEBUG   (  263):          be9b42f8  400d6000  /system/lib/libc.soI/DEBUG   (  263):          be9b42fc  752e5bf1  I/DEBUG   (  263):          be9b4300  752e5bf1  I/DEBUG   (  263):          be9b4304  752e5b70  I/DEBUG   (  263):          be9b4308  752e5bc0  I/DEBUG   (  263):          be9b430c  00000000  I/DEBUG   (  263):          ........  ........


adb logcat | $NDKROOT/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi

$NDKROOT/ndk-stack -sym obj/local/armeabi/ -dump exception.log


********** Crash dump: **********Build fingerprint: ‘test-keys'pid: 14337, tid: 14337, name: example.testjni  >>> com.example.testjni <<<signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 752cb0fcStack frame #00  pc 00000bbe  /data/app-lib/com.example.testjni-1/libjnitest.so (Java_com_example_testjni_MainActivity_add+5): Routine Java_com_example_testjni_MainActivity_add at /home/luohaitao/work/android/ndk/android-ndk-r9d/samples/testJNI/jni/com_example_testjni_MainActivity.cpp:6Stack frame #01  pc 0002044c  /system/lib/libdvm.so (dvmPlatformInvoke+112)Stack frame #02  pc 000512b3  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)Stack frame #03  pc 0003b83d  /system/lib/libdvm.so (dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+8)Stack frame #04  pc 00052cb5  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+184)Stack frame #05  pc 000298e0  /system/lib/libdvm.soStack frame #06  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)Stack frame #07  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)Stack frame #08  pc 00063a11  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+392)Stack frame #09  pc 0006b873  /system/lib/libdvm.soStack frame #10  pc 000298e0  /system/lib/libdvm.soStack frame #11  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)Stack frame #12  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)Stack frame #13  pc 0006372d  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)Stack frame #14  pc 0004ce9b  /system/lib/libdvm.soStack frame #15  pc 0003fe05  /system/lib/libdvm.soStack frame #16  pc 0004fb7f  /system/lib/libandroid_runtime.soStack frame #17  pc 000508c5  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+388)Stack frame #18  pc 0000105b  /system/bin/app_processStack frame #19  pc 0000e593  /system/lib/libc.so (__libc_init+50)Stack frame #20  pc 00000d7c  /system/bin/app_process