首页 > 代码库 > javah 生成.h文件时出现的错误

javah 生成.h文件时出现的错误

javah 時出現错误: 无法访问android.app.Activity,找不到android.app.Activity的类文件  

"Run TestJni1" 或 "Debug TestJni1" 后,"D:\workspace\testjni1\bin\classes\com\example\testjni1" 目錄下會產生很多 *.class 文件,對其中的 "MainActivity.class" 進行如下操作,據說會生成所需頭文件。但實際運作發現不行。

*********************************** 以下是操作過程 ********************************************************
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\Administrator>d:

D:\>cd \workspace\testjni1\bin

D:\workspace\testjni1\bin>javah -d header -classpath classes -jni com.example.testjni1.MainActivity
错误: 无法访问android.app.Activity
  找不到android.app.Activity的类文件
*********************************** 以上是操作過程 ********************************************************

據說在 src 目錄下也可以獲得頭文件,我試過了,是可以的。

*********************************** 以下是操作過程 ********************************************************
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\Administrator>d:

D:\>cd \workspace\testjni1\src
D:\workspace\testjni1\src>javah com.example.testjni1.MainActivity

D:\workspace\testjni1\src>dir
 驱动器 D 中的卷没有标签。
 卷的序列号是 000C-6D9F

 D:\workspace\testjni1\src 的目录

2013/03/09  10:57    <DIR>          .
2013/03/09  10:57    <DIR>          ..
2013/03/09  10:38    <DIR>          com
2013/03/09  10:57               726 com_example_testjni1_MainActivity.h
               1 个文件            726 字节
               3 个目录 10,670,010,368 可用字节

D:\workspace\testjni1\src>
*********************************** 以上是操作過程 ********************************************************

这招其實是對 "D:\workspace\testjni1\src\com.example\testjni1\MainActivity.java" 進行操作,可以在 ‘src‘ 目錄下获得一個 ‘com_example_testjni1_MainActivity.h" 头文件,但是經檢驗這個文件裡面沒多少東西。

 

最可靠的方法还是为 javah 指明 android.jar 的路徑,會比較好。 

*********************************** 以下是操作過程 ********************************************************
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\Administrator>d:

D:\>cd workspace\tstjni1\bin

D:\workspace\testjni1\bin>javah -d heafer -classpath c:\adt-bundle-windows-x86_64\adt-bundle-windows-x86_64-20130219\sdk\platforms\android-17\android.jar;classes -jni com.example.testjni1.MainActivity

D:\workspace\testjni1\bin>dir
 驱动器 D 中的卷没有标签。
 卷的序列号是 000C-6D9F

 D:\workspace\testjni1\bin 的目录

2013/03/09  13:58    <DIR>          .
2013/03/09  13:58    <DIR>          ..
2013/03/09  13:16               880 AndroidManifest.xml
2013/03/09  13:16    <DIR>          classes
2013/03/09  13:33           448,812 classes.dex
2013/03/09  13:58             3,938 com_example_testjni1_MainActivity.h
2013/03/09  13:33    <DIR>          dexedLibs
2013/03/09  13:39    <DIR>          header
2013/03/09  13:33           196,360 testjni1.apk
2013/03/09  13:33    <DIR>          res
2013/03/09  13:33            40,788 resources.ap_
               5 个文件        690,778 字节
               6 个目录 10,671,005,696 可用字节

D:\workspace\testjni1\bin>

*********************************** 以上是操作過程 ********************************************************

【本人通过上面方法解决了问题,操作如下】********************* START  *********************************

Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\Administrator>cd..

C:\Users>cd..

C:\>d:

D:\>cd D:\software\adt\android-ndk-r8d\samples\hello-jni

D:\software\adt\android-ndk-r8d\samples\hello-jni>javah -classpath bin/classes;D
:\software\adt\sdk\platforms\android-17\android.jar -d ndk com.example.hellojni.
HelloJni

D:\software\adt\android-ndk-r8d\samples\hello-jni>

**************************************  END ************************************************

 

這次獲得的頭文件裡面內容多了很多。

*********************************** 以下是第一次獲得的頭文件 ******************************************
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_testjni1_MainActivity */

#ifndef _Included_com_example_testjni1_MainActivity
#define _Included_com_example_testjni1_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_testjni1_MainActivity
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_add
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     com_example_testjni1_MainActivity
 * Method:    sub
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_sub
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif
*********************************** 以上是第一次獲得的頭文件 ******************************************

*********************************** 以下是第二次獲得的頭文件 ******************************************
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_testjni1_MainActivity */

#ifndef _Included_com_example_testjni1_MainActivity
#define _Included_com_example_testjni1_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_testjni1_MainActivity_MODE_PRIVATE
#define com_example_testjni1_MainActivity_MODE_PRIVATE 0L
#undef com_example_testjni1_MainActivity_MODE_WORLD_READABLE
#define com_example_testjni1_MainActivity_MODE_WORLD_READABLE 1L
#undef com_example_testjni1_MainActivity_MODE_WORLD_WRITEABLE
#define com_example_testjni1_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_testjni1_MainActivity_MODE_APPEND
#define com_example_testjni1_MainActivity_MODE_APPEND 32768L
#undef com_example_testjni1_MainActivity_MODE_MULTI_PROCESS
#define com_example_testjni1_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_example_testjni1_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_testjni1_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_testjni1_MainActivity_BIND_AUTO_CREATE
#define com_example_testjni1_MainActivity_BIND_AUTO_CREATE 1L
#undef com_example_testjni1_MainActivity_BIND_DEBUG_UNBIND
#define com_example_testjni1_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_testjni1_MainActivity_BIND_NOT_FOREGROUND
#define com_example_testjni1_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_testjni1_MainActivity_BIND_ABOVE_CLIENT
#define com_example_testjni1_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_testjni1_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_testjni1_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_testjni1_MainActivity_BIND_WAIVE_PRIORITY
#define com_example_testjni1_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_testjni1_MainActivity_BIND_IMPORTANT
#define com_example_testjni1_MainActivity_BIND_IMPORTANT 64L
#undef com_example_testjni1_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_testjni1_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_testjni1_MainActivity_CONTEXT_INCLUDE_CODE
#define com_example_testjni1_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_testjni1_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_example_testjni1_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_testjni1_MainActivity_CONTEXT_RESTRICTED
#define com_example_testjni1_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_example_testjni1_MainActivity_RESULT_CANCELED
#define com_example_testjni1_MainActivity_RESULT_CANCELED 0L
#undef com_example_testjni1_MainActivity_RESULT_OK
#define com_example_testjni1_MainActivity_RESULT_OK -1L
#undef com_example_testjni1_MainActivity_RESULT_FIRST_USER
#define com_example_testjni1_MainActivity_RESULT_FIRST_USER 1L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_DISABLE
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_DIALER
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
 * Class:     com_example_testjni1_MainActivity
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_add
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     com_example_testjni1_MainActivity
 * Method:    sub
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_sub
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif
*********************************** 以上是第二次獲得的頭文件 ******************************************

 

两个文件明显很不同,但网上看到,大家一般认为两者无区别。我只能這樣告訴你——不要開玩笑了好嗎?

 

Android使用NDK开发项目时的一些问题

1、
在使用NDK的过程中,有一个步骤是根据生成的 .class 文件生成相应的 .h 文件。
网上相关文档给出的方式是使用如下命令:
cd <project dir>
mkdir jni
javah -calsspath bin -d jni <class>

即,进入工程目录,创建一个jni的文件夹。
然后调用javah命令通过bin目录下的 .class 文件生成 .h 文件并放到jni文件夹中。
需要注意的是,这里的 <class> 是以 包名.类名 的形式指定的,不能省略包名。
但是,运行后出现如下错误:
错误:无法访问 <class>
未找到 <class> 的类文件
javadoc: 错误 - 找不到类 <class>。
Error: 未在命令行中指定任何类。请尝试使用 -help。

后来发现,生成的 .class 文件并不是直接放到bin文件夹下的,而是包含一个名为classes的子目录。
所以,把以上命令改为:
javah -calsspath bin/classes -d jni <package>.<class>
【本人也出现这个问题,通过上面把 “bin” 修改为 “bin/classes” 解决问题 】

2、
运行后,又出现了以下错误:
错误:无法访问 <class>
错误的类文件: <class file>
类文件具有错误的版本 50.0,应为 49.0
请删除该文件或确保该文件位于正确的类路径子目录中。
com.sun.tools.javac.util.Abort
    at com.sun.tools.javac.comp.Check.completionError(Check.java:169)
    at com.sun.tools.javadoc.DocEnv.loadClass(DocEnv.java:149)
    at com.sun.tools.javadoc.RootDocImpl.<init>(RootDocImpl.java:77)
    at com.sun.tools.javadoc.JavadocTool.getRootDocImpl(JavadocTool.java:156)
    at com.sun.tools.javadoc.Start.parseAndExecute(Start.java:330)
    at com.sun.tools.javadoc.Start.begin(Start.java:128)
    at com.sun.tools.javadoc.Main.execute(Main.java:66)
    at com.sun.tools.javah.Main.main(Main.java:147)
javadoc: 错误 - 致命错误

这个错误是由于jdk版本不一致造成的。
Eclipse创建 .class文件使用的jdk版本是1.6,而运行javah命令使用的是1.5版本。
修改方法,可以设置Eclipse中的jdk版本,也可以修改系统环境对应的java版本。
总之,使各个命令使用的jdk的版本保持一致即可。

3、
当根据 .h 文件编写好 .c 及 Android.mk 文件之后,需要通过NDK命令编译为 .so 文件。
需要将ndk安装目录添加到环境变量中,然后在jni目录下执行命令 ndk-build 命令。
但是,在 r7 版本下会报以下错误:
<ndk>/prebuilt/linux-x86/bin/awk: 无法执行二进制文件
Android NDK: Host ‘awk‘ tool is outdated. Please define HOST_AWK to ...
<ndk>/build/core/init.mk:258: *** Android NDK: Aborting.    。 停止。

这个错误是因为 ndk 包中的awk命令与我当前系统版本不符。
如果系统本身是存在awk命令的话,只需将 <ndk>/prebuilt/linux-x86/bin/awk 删除或者重命名即可。

4、
如果 .so 文件编译成功,会在项目目录下生成文件夹 libs/armeabi,相应的 .so 文件就在该目录下。
打包APK时,会自动将该目录包含进去,保证程序执行时,能够找到相应的库。
但是,我在运行最终生成的APK时,却出错,提示找不到库:
java.lang.UnsatisfiedLinkError: Couldn‘t load <so>: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:429)
at java.lang.System.loadLibrary(System.java:554)

这个错误是因为,库的命名是有规则的。
在Android.mk文件中通过LOCAL_MODULE定义库的名字时,不要加前缀lib和后缀 .so。
在生成 .so 文件时,会自动添加前缀lib和后缀 .so。
在java中调用System.loadLibrary()时,参数与LOCAL_MODULE定义的名字要保持一致。
另外,如果定义LOCAL_MODULE时添加了前缀lib,则在生成 .so 文件时,不会再重复添加前缀lib。
这时候,自动生成的 .so 文件只比定义多了一个后缀 .so。
但是在java中,仍然不要加前缀lib,也就是与LOCAL_MODULE不加前缀时的情形是一样的。

【转自】http://hi.baidu.com/gaogaf/item/c20d5abf1a073b42bb0e1277

【转自】http://blog.163.com/xdma_tw/blog/static/16610932920132910513108/

 

javah 生成.h文件时出现的错误