在开发NDK程序时,javah工具分析编译完成的使用了声明了原生代码的Java类文件(*.class),自动生成符合JNI规定的原生函数声明。如:
private native int func(int i);
经过javah命令分析后,自动生成的头文件包含其对应的声明为:
JNIEXPORT jint JNICALL Java_com_example_func_MainActivity_func(JNIEnv *, jobject, jint);
在Eclipse下,可以使用宏和系统环境变量等构件自动的工具,只需要点击这个自制的工具就能完成javah的命令。但是在Android Studio中,我目前还没有找到这种方法,只能打开Android Studio自带的Terminal,手动输入命令。假定我们创建的项目为Func, 在Android Studio的工作目录下,该项目的Java类的目录路径为Func/app/src/main/java/com/example/func/MainActivity.java,JNI代码的目录路径为Func/app/src/main/jni/func.cpp,Java类生成的类文件(*.class)路径为Func/app/build/intermediates/classes/debug/com/example/func/,Android SDK的支持jar包的路径在我的Mac上为/Users/my_name/Library/Android/sdk/platforms/android-21/android.jar,所以,进入Func/app/目录,执行javah命令:
javah -classpath ./build/intermediates/classes/debug/com/example/func:/Users/my_name/Library/Android/sdk/platforms/android-21/android.jar -jni -d ./src/main/jni -force com.example.func.MainActivity
命令中的参数都是上面假定的,根据个人的情况做相应的调整。其中
-classpath参数说明后面的字符串指定了本项目Java类文件(*.class)以及Java中使用到的如Activity等Android定义的组建的类文件的路径。
./build/intermediates/classes/debug/com/example/func:/Users/my_name/Library/Android/sdk/platforms/android-21/android.jar
包含了两个路径,在Linux、BSD和Mac中使用冒号”:”隔开,在Windows下使用分号”;”隔开。
-d参数指定生成头文件的输出目录,我们想要头文件在jni目录下。
-force参数说明强行覆盖已存在的头文件。
这里,我遇到了一个问题。在Java文件中,定义的类如果是extends Activity, 那么上述的命令就可以正常完成,如果是extends ActionBarActivity,那么就会报android.support.appcompet-v7…找不到,我估计是没有在路径中提供ActionBarActivity的支持jar包。现在还没在Mac上找到这个Jar包。网上有说是在SDK_HOME/extras/android/support/android-appcompet-v7.jar,但是我在这个目录下没找到这个jar包。留待以后解决。