Android Studio NDK JNI 实践

来源:互联网 发布:java字符串数组定义 编辑:程序博客网 时间:2024/06/07 22:45

环境要求

1 . Android Studio2.2 以上

2.2 以上版本的Android Studio会自动下载ndk-bundle 并配置好ndk路径

具体步骤

1 . 新建一个项目名字随意取名,我这边叫做NDKTest 一路next 直到finish 创建完成。
image
2 . 在项目工程目录的src/main建立jni目录,如果有就不要在新建了。
3 . 新建Android.mk文件 内容如下

LOCAL_PATH       :=  $(call my-dir)# 设置工作目录,而my-dir则会返回Android.mk文件所在的目录include              $(CLEAR_VARS)# 清除几乎所有以LOCAL——PATH开头的变量(不包括LOCAL_PATH)LOCAL_MODULE     :=  hello_jni# 设置模块的名称,即编译出来.so文件名# 注,要和上述步骤中build.gradle中NDK节点设置的名字相同LOCAL_SRC_FILES  :=  test.cpp# 指定参与模块编译的C/C++源文件名include              $(BUILD_SHARED_LIBRARY)# 指定生成的静态库或者共享库在运行时依赖的共享库模块列表。

4 . 新建Application.mk文件,内容如下:

APP_ABI := rmeabi x86 mips# 最常用的APP_ABI字段:指定需要基于哪些CPU平台的.so文件# 常见的平台有armeabi x86 mips,其中移动设备主要是armeabi平台# 默认情况下,Android平台会生成所有平台的.so文件,即同APP_ABI := armeabi x86 mips# 指定CPU平台类型后,就只会生成该平台的.so文件,即上述语句只会生成armeabi平台的.so文件

5 . 新建test.cpp文件 内容如下

# include <jni.h># include <stdio.h>extern "C"{    JNIEXPORT jstring JNICALL Java_com_lzc_ndktest_MainActivity_getFromJNI(JNIEnv *env, jobject obj ){       // 参数说明       // 1. JNIEnv:代表了VM里面的环境,本地的代码可以通过该参数与Java代码进行操作       // 2. obj:定义JNI方法的类的一个本地引用(this)    return env -> NewStringUTF("Hello i am from JNI!");    // 上述代码是返回一个String类型的"Hello i am from JNI!"字符串    }}

Java_com_lzc_ndktest_MainActivity_getFromJNI 命名规则

  • Java是必写后接_
  • 中间的com_lzc_ndktest是将应用包名com.lzc.ndktest的.替换成即可后接
  • MainActivity是加载动态库使用的类文件
  • getFromJNI 是jni方法的名称
  • 如果包名中存在_ 则对应的替换成_1

最后三个文件位置如下图所示:

image

6 . 定位到jni目录下 执行ndk-build,完成后在工程目录的main文件夹下生成libs和obj文件夹,如下图:
image
将main目录下的libs文件夹里面的文件复制到工程目录下的libs中。
image
7. 在app的build.gradle文件中添加如下代码:

android{    .... sourceSets {        main {            jniLibs.srcDirs = ['libs']//            jniLibs.srcDir 'src/main/libs'//            java.srcDirs += 'src/main/jni/src'//            assets.srcDirs += 'src/main/jni/assets'        }    }....}

8 . 在MainActivity中添加如下代码:

//加载动态库 不用写前面的lib static {        System.loadLibrary("hello_jni");    }    // 步骤2:定义在JNI中实现的方法    public native String getFromJNI();

9 . 调用事例,如下所示:

  @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        TextView textView= (TextView) findViewById(R.id.text_hello_jni);        textView.setText(getFromJNI());    }

10 . 运行结果图

原创粉丝点击