先说javah万年坑
javah语法:
Usage:
javah [options] <classes>
where [options] include:
-o <file> Output file (only one of -d or -o may be used)
-d <dir> Output directory
-v -verbose Enable verbose output
-h --help -? Print this message
-version Print version information
-jni Generate JNI-style header file (default)
-force Always write output files
-classpath <path> Path from which to load classes
-bootclasspath <path> Path from which to load bootstrap classes
<classes> are specified with their fully qualified names
(for example, java.lang.Object).
在MainActivity中函数
先make project 生成 class文件,然后如下:
mac与windows下 javah的使用不尽相同:
注意HelloJni.class是个二进制文件,假设当前文件夹目录是aa 那么其下就是 com\example\hellojni\HelloJni.class的结构
在classpath 类路径下 编译 com.example.hellojni.HelloJni 变成 .h文件
windows下 (;)
javah -classpath .;F:\\aa\\android.jar -d jni com.example.hellojni.HelloJni
mac下(:)
javah -classpath .:/Users/wyj/Desktop/a/android.jar -d jj com.example.hellojni.HelloJni
否则就一直报错说找不到
写好Android.mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c include $(BUILD_SHARED_LIBRARY)
解决了javah之后,在命令提示符中切换到jni的上一级目录 输入命令ndk-build 编译出 *.so文件
在android studio中 把相应的 armeabi/*.so 文件结构
在main中建立 jniLibs文件夹 然后把 armeabi/*.so 拷贝进去 然后就可以访问了。
在 jniLibs.srcDirs = ['xxx'] //这里xxx代表一个目录。可以改变jniLibs的读取路径 , 默认的 jniLibs结构是 src/main/jniLibs
ndk生成的so文件 只能 给 具有该目录包结构的 *.java 用,放到其它工程中 包不对应则不能用。
例如:.c文件中的函数为
JNIEXPORT jstring JNICALL Java_com_example_wyj_myapplication_MainActivity_stringFromJNI 能够使用的类的结构 必须是 com.example.wyj.myapplication 文件包结构的 MainActivity类 下面的 stringFromJNI 函数才能被用
放入其它工程如果不是遵从这个结构的 会报错,函数找不到, 当然*.so可以加载。 使用的时候 在MainActivity.java中
public static native String stringFromJNI();
static {
System.loadLibrary("hello");
}