android studio用Javah创建.h头文件和编译运行

android studio 初步JNI开发

android studio在原有项目中使用cmake构建JNI

android studio用Javah创建.h头文件和编译运行

android studio继续深入ndk打包so库和jar Api


首先一如既往的创建library module:jnilib,然后在jnilib\src\main\java目录中新建类JniUtil如下:

package com.example.jnilib;
public class JniUtil {
    static {
        System.loadLibrary("jnido");
    }

    public native String getInfo();
}
在AS的terminal窗口执行如下命令

D:\xx\android\workstudio\TestJni>cd jnilib\src\main\java

D:\xx\android\workstudio\TestJni\jnilib\src\main\java>javah -jni com.example.jnilib.JniUtil

几秒钟后在此目录下会创建一个头文件com_example_jnilib_JniUtil.h,如下图

android studio用Javah创建.h头文件和编译运行_第1张图片

然后把这个头文件移动到jni目录下,如果你要是觉得这么复制太麻烦可以用下面的命令直接在jni目录下创建头文件:

javah -d ..\jni com.example.jnilib.JniUtil

在jni目录下新建jnido.cpp,并且引入刚创建的.h头文件,同时实现头文件定义的函数,实现函数时注意参数和头文件中定义的有所不同,定义时只定义参数类型,没有定义参数名:

#include 

JNIEXPORT jstring JNICALL Java_com_example_jnilib_JniUtil_getInfo(JNIEnv *env, jobject instance){
     return env->NewStringUTF("Hello jni");
 }

在jni目录下创建Android.mk编译文件,文件内容如下:

#每个Android.mk文件必须以LOCAL_PATH开头,在整个开发中,它通常别用做定位资源文件,例如,功能宏my-dir提供给编译系统当前的路径。
LOCAL_PATH := $(call my-dir)
#CLEAR_VARS指编译系统提供一个特殊的GUN MakeFile来为你清除所有的LOCAL_XXX变量,LOCAL_PATH不会被清除。使用这个变量是因为在编译系统时,所有的控制文件都会在一个GUN Make上下文进行执行,而在此上下文中所有的LOCAL_XXX都是全局的。
include $(CLEAR_VARS)
#LOCAL_MODULE变量是为了确定模块名,并且必须要定义。这个名字必须是唯一的同时不能含有空格。会自动的为文件添加适当的前缀或后缀,模块名为“foo”它将会生成一个名为“libfoo.so”文件。
LOCAL_MODULE    := jnido
#包含一系列被编译进模块的C 或C++资源文件
LOCAL_SRC_FILES := jnido.cpp
#指明一个GUN Makefile脚本,并且收集从最近“include$(CLEAR_VARS)”下的所有LOCALL_XXX变量的信息,最后告诉编译系统如何正确的进行编译。将会生成一个静态库hello-jni.a文件。
include $(BUILD_SHARED_LIBRARY)

在gradle中需要如下配置

externalNativeBuild {
    ndkBuild {
        path file("src\\main\\jni\\Android.mk")
    }
}

现在在主module中添加dependency依赖这个新建的library module,并且引用JniUtil的方法:

TextView info= (TextView) findViewById(R.id.info);
info.setText(JniUtil.getInfo());

点击run编译并运行,会有如下报错:

Error:Execution failed for task ':jnilib:compileReleaseNdk'.

> Error: Your project contains C++ files but it is not using a supported native build system.

意思是项目中没有使用NDK的配置,解决方法是在gradle.properties文件中添加如下配置:
android.useDeprecatedNdk=true

需要注意的是你的jni所在module 的gradle需要如下配置,一般来说在创建jnifolder时就已经自动创建了:

sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } }

现在就可以正常运行程序了,运行后会自动生成.so文件:

android studio用Javah创建.h头文件和编译运行_第2张图片


你可能感兴趣的:(android)