最近一个小项目要求自己写个jni动态库,碰到了各种各样的问题,eclipse ndk配置,jni头文件的生成,Android.mk的编写,环境变量的配置等等。。。。。。
反正就是搞的很烦,一点小东西,这里出错那里出错,因此在此总结出来,供以后使用,也供大家交流。
第一步:首先下载jdk,android sdk4.2,android ndk
第二步:环境变量配置
右击“我的电脑”->“属性”->“高级”
点击“环境变量”
选中path,点“编辑”
修改变量值:在变量值后面添加:
D:\zycheng\tools\adt-bundle-windows-x86-20130522\adt-bundle-windows-x86-
20130522\sdk\platform-tools;D:\zycheng\tools\adt-bundle-windows-x86-20130522\adt
-bundle-windows-x86-20130522\sdk\tools;C:\Program Files\Java\jdk1.8.0_25\bin;
然后点击确定,配置ok
在windows中打开一个命令窗口,查看是否配置ok
进入窗口输入命令:path
查看是否有添加的路径,有,配置成功
第三步:eclipse ndk配置
1.在eclipse中右击工程选择“porperties”--->选中"builders"
点击“new”---->选中“program”
点击“ok”
这个过程网上有教程,我就简单记录了
第四步:jni头文件生成
第五步:jni文件编写(将生产的.h文件修改为后缀名为.c或者.cpp,完善函数实现你需要的功能就可以了)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_chargedemo_MainActivity */
#ifndef _Included_com_example_chargedemo_MainActivity
#define _Included_com_example_chargedemo_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_chargedemo_MainActivity_MODE_PRIVATE
#define com_example_chargedemo_MainActivity_MODE_PRIVATE 0L
#undef com_example_chargedemo_MainActivity_MODE_WORLD_READABLE
#define com_example_chargedemo_MainActivity_MODE_WORLD_READABLE 1L
#undef com_example_chargedemo_MainActivity_MODE_WORLD_WRITEABLE
#define com_example_chargedemo_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_chargedemo_MainActivity_MODE_APPEND
#define com_example_chargedemo_MainActivity_MODE_APPEND 32768L
#undef com_example_chargedemo_MainActivity_MODE_MULTI_PROCESS
#define com_example_chargedemo_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_example_chargedemo_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_chargedemo_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_chargedemo_MainActivity_BIND_AUTO_CREATE
#define com_example_chargedemo_MainActivity_BIND_AUTO_CREATE 1L
#undef com_example_chargedemo_MainActivity_BIND_DEBUG_UNBIND
#define com_example_chargedemo_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_chargedemo_MainActivity_BIND_NOT_FOREGROUND
#define com_example_chargedemo_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_chargedemo_MainActivity_BIND_ABOVE_CLIENT
#define com_example_chargedemo_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_chargedemo_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_chargedemo_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_chargedemo_MainActivity_BIND_WAIVE_PRIORITY
#define com_example_chargedemo_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_chargedemo_MainActivity_BIND_IMPORTANT
#define com_example_chargedemo_MainActivity_BIND_IMPORTANT 64L
#undef com_example_chargedemo_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_chargedemo_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_chargedemo_MainActivity_CONTEXT_INCLUDE_CODE
#define com_example_chargedemo_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_chargedemo_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_example_chargedemo_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_chargedemo_MainActivity_CONTEXT_RESTRICTED
#define com_example_chargedemo_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_example_chargedemo_MainActivity_RESULT_CANCELED
#define com_example_chargedemo_MainActivity_RESULT_CANCELED 0L
#undef com_example_chargedemo_MainActivity_RESULT_OK
#define com_example_chargedemo_MainActivity_RESULT_OK -1L
#undef com_example_chargedemo_MainActivity_RESULT_FIRST_USER
#define com_example_chargedemo_MainActivity_RESULT_FIRST_USER 1L
#undef com_example_chargedemo_MainActivity_DEFAULT_KEYS_DISABLE
#define com_example_chargedemo_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_chargedemo_MainActivity_DEFAULT_KEYS_DIALER
#define com_example_chargedemo_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_chargedemo_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_chargedemo_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_chargedemo_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_chargedemo_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_chargedemo_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_chargedemo_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
* Class: com_example_chargedemo_MainActivity
* Method: chargerVoltage
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_chargedemo_MainActivity_chargerVoltage
(JNIEnv *, jobject);
/*
* Class: com_example_chargedemo_MainActivity
* Method: chargerCurrent
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_chargedemo_MainActivity_chargerCurrent
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
第六步:Android.mk编写
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# for logging
LOCAL_LDLIBS += -llog
LOCAL_MODULE := libchargejni //在java中调用库的名字为chargejni
LOCAL_SRC_FILES := libchargejni.cpp
include $(BUILD_SHARED_LIBRARY)
问题汇总:
一.遇到的最蛋疼的就是jni头文件的生成,看来网上好多 的人建议就是没成功过,最后无意中竟然成功了。。。。
1.按照正常的流程是:配置好环境变量,直接到android工程下的bin目录下执行:javah -jni com.example.chargedemo.MainActivity(包名+类名,并且申明了本地方法)就应该是ok的,但是
D:\zycheng\workspace\ChargeDemo\bin>javah -jni com.example.chargedemo.MainActivity
错误: 找不到 'com.example.chargedemo.MainActivity' 的类文件。
于是乎问度娘
然后找到各种命令:
1.进入到bin\classes\执行:javah -jni com.example.chargedemo.MainActivity
D:\zycheng\workspace\ChargeDemo\bin\classes>javah -jni com.example.chargedemo.MainActivity
错误: 无法访问android.app.Activity 找不到android.app.Activity的类文件
这个错误意思是没有找到Activity这个类
2.进入到src目录下执行:javah -jni com.example.chargedemo.MainActivity
D:\zycheng\workspace\ChargeDemo\src>javah -jni com.example.chargedemo.MainActivi
ty
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 编码GBK的不可映射字符
错误: 非法字符: '#'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0000'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u007f'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0019'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ue2b7'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ue099'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u001d'
错误: 非法字符: '\u0005'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0014'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u001e'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u250a'
错误: 非法字符: '\ue01f'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ue31a'
错误: 非法字符: '\u000b'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ue7a0'
错误: 非法字符: '\u001d'
错误: 非法字符: '\ufffd'
错误: 非法字符: '#'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u000e'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0017'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u001e'
错误: 非法字符: '\ue046'
错误: 非法字符: '\u0000'
错误: 非法字符: '\ufffd'
错误: 非法字符: '`'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0012'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u001a'
错误: 非法字符: '\u0010'
错误: 非法字符: '\'
错误: 非法字符: '\ue854'
错误: 非法字符: '\ue5e5'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0002'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ue5ad'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u001d'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0008'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ue4b5'
错误: 非法字符: '\u0008'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u007f'
错误: 非法字符: '\u001f'
错误: 非法字符: '\u001a'
错误: 非法字符: '\ufffd'
错误: 需要class, interface或enum
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0008'
错误: 非法字符: '\ufffd'
错误: 非法字符: '`'
错误: 非法字符: '\ue0ad'
错误: 非法字符: '\ue515'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ue065'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0003'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0017'
错误: 非法字符: '\ue6e8'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '`'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u001e'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0000'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u0001'
错误: 非法字符: '\ue707'
错误: 非法字符: '\u001a'
错误: 非法字符: '\ufffd'
错误: 非法字符: '\u001b'
错误: 非法字符: '\ufffd'
看到这错误完全不明所以。。。。。。。。。。。。。。
3.又回到bin目录下面执行:D:\zycheng\workspace\ChargeDemo\bin>javah -d aaa -classpath D:\zycheng\tools\adt
-bundle-windows-x86-20130522\adt-bundle-windows-x86-20130522\sdk\platforms\andro
id-17\android.jar;classes -jni com.example.chargedemo.MainActivity
ok了,在aaa目录下面生成了com_example_chargedemo_MainActivity.h
总算是告一段落了