Android版本不断更新,发现网上很多JNI的教程,都不太适用了,会遇到各种问题,今天自己来总结一个。

NDK下载

我们下载NDK,有两种下载方式:

  

  点击SDK Manger -> SDK Tools -> NDK -> 点击Apply

  OK,NDK下载完成

NDK配置

  我们先创建一个项目,里面只有一个MainActivity

右键项目 -> Open Module settings-> Android NDK Location -> OK -> 等待编译

我们发现根目录local.properties里面多了NDK路径如下图:

示例代码

1. 在MainActivity的包下,新建一个类,声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。

public class myJNI {

  //加载so库
static {
System.loadLibrary("JniTest");
}   //native方法
public static native String sayHello(); }

2. 打开android studio终端,使用javac编译上述文件,生成class文件。

yuany@Mobile238:~/workspace/DemoJNI2$ cd app/src/main/java/com/example/scarecrow/demojni/
yuany@Mobile238:~/workspace/DemoJNI2/app/src/main/java/com/example/scarecrow/demojni$ javac myJNI.java

3. 确认自己类的包名!然后在上一级的位置使用javah生成.h头文件

一定要在上一级哦,不然不会报错:找不到xxx类

yuany@Mobile238:~/workspace/DemoJNI2/app/src/main/java/com/example/scarecrow/demojni$ cd ~/workspace/DemoJNI2/app/src/main/java/
yuany@Mobile238:~/workspace/DemoJNI2/app/src/main/java$ javah -jni com.example.scarecrow.demojni.myJNI

然后就能看到生成了一个h文件。

4. 接下来在项目中创建一个jni目录,并将刚生成的.h文件剪切至这个目录下

5. 在jni目录下新建MyJNI.cpp文件,实现com_example_scarecrow_demojni_myJNI.h中的方法,返回一句话"This is my first JNI test"。

#include "com_example_scarecrow_demojni_myJNI.h"

JNIEXPORT jstring JNICALL Java_com_example_scarecrow_demojni_myJNI_sayHello
(JNIEnv * env, jclass jobj)
{
//返回一句话
return env->NewStringUTF("This is my first JNI test");
}

6. 打开app Module的build.gradle文件,在defaultConfig节点里添加以下代码, 注意这里的moduleName,是我们在之前自己编写的类里面加载的so库名。 abiFilters 对应不同的操作系统版本。
        ndk {
moduleName "JniTest"
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}

7. 编译代码 Build -> Make Project. 这时候会看到报错如下。

Error: Your project contains C++ files but it is not using a supported native build system.
Consider using CMake or ndk-build integration. For more information, go to:
https://d.android.com/r/studio-ui/add-native-code.html
Alternatively, you can use the experimental plugin:
https://developer.android.com/r/tools/experimental-plugin.html

意思是要把我们的native c++代码编译到库里面,需要Android.mk文件,而且这个文件在我们尝试make的时候, 已经帮我们生成好了(真是暖心)。。 位置就在

project-root/module-root/build/intermediates/ndk/debug/Android.mk.

OK, 接下来我们要做的就是把这个Android.mk文件移动到build.gradle的同级目录。官方说法是This makes sure that Gradle doesn't delete the script file when running the clean task.

8. Link Gradle to the Android.mk file .

在Module(app)上右键Link C++ Project with Gradle, Build System选择ndk-build,然后查找到 Android.mk文件,提示Path to be saved into the build.gradle file: "Android.mk", 点OK.

9. rebuild project.

在项目的app\build\intermediates\ndkBuild\debug\obj\local 路径下, 会看到为不同的系统生成的so库。

10.在MainActivity中调用JNI方法。

修改MainActivity代码,设置TextView, (Layout的修改并没有写在这里),在emulator上运行app, 可以看到显示出在c++代码中返回的话。

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//invoke jni function
TextView view = findViewById(R.id.text);
view.setText(myJNI.sayHello());
}
}

至此通过静态注册的方法,编写JNI代码的流程已经介绍完了。关于如何通过动态注册的方式调用JNI方法,请参考后续的介绍。

AndroidStudio 开发JNI的更多相关文章

  1. AndroidStudio开发工具快捷键

    在这里,自己整理了下在使用AndroidStudio开发工具所使用到的一些快捷键提示,也出于在开发过程中节省时间提升效率,然而可能多数开发者之前使用的都是Eclipse开发工具,可能开始都不习惯,但是 ...

  2. NDK工具开发Jni,Android studio jni开发

    NDK工具开发JNI 对于JNI的作用,我这边就不详细说明了,百度google 有很多这样的介绍,这边着重详解AS使用NDK工具开发,调C的流程. 1,创建工程 2,创建native方法 //该类的路 ...

  3. Android NDK开发 JNI操作java构造方法,普通方法,静态方法(七)

    Android NDK开发 JNI操作java普通.静态.构造方法 1.Jni实例化一个Java类的实例jobject 1.通过FindClas( ),获取Java类的的jclass 2.通过GetM ...

  4. c++ 开发JNI

    c++ 开发JNI C的预处理命令 #开头的就是c/c++的预处理命令 在编译之前 先会走预编译阶段 预编译阶段的作用就是 把 include进来的头文件 copy到源文件中 define这些宏定义 ...

  5. Android-studio开发 快捷键

    这会儿正在学android开发,使用的是Android-studio 记录一下开发工具默认的 快捷键

  6. Android Studio开发JNI工程

    转:http://www.2cto.com/kf/201412/361768.html 使用Android Sutdio创建一个新的工程后,接下来记录创建NDK工程的基本步骤. 本文将达到: 1. 创 ...

  7. Android Studio NDK开发-JNI调用Java方法

    相对于NDK来说SDK里面有更多API可以调用,有时候我们在做NDK开发的时候,需要在JNI直接Java中的方法和变量,比如callback,系统信息等.... 如何在JNI中调用Java方法呢?就需 ...

  8. 使用Android-studio开发移动app与weex结合开发详细步骤

    详细步骤如下:   首先,确保机器已经安装了node.js,并且把npm更新到最新版本 下载完毕后,我们可以看到全局目录下的node_modules下面多出一个weex-toolkit 同时,我们留意 ...

  9. Android4.2.2NDK和源代码开发jni的异同

    C/C++开发,在NDK和源代码中输出Log信息的方法! NDK: 1.包括头文件 #include <android/log.h> 2.Android.mk中包括库 LOCAL_LDLI ...

随机推荐

  1. 在虚拟环境下运行 Confluence 6

    这个页面针对运行在虚拟硬件环境下的 Confluence 提供一些信息. 概要 在虚拟环境(virtual machine (VM))下运行 Confluence 需要一些特定的技能来进行设定和进行管 ...

  2. regex back-reference

    \<number>表示反向引用,引用group(number)表示的内容 最外层括号的group-id就是1,向内依次增加 ")) # output is [('111', '1 ...

  3. vue组件利用formdata图片预览以及上传

    转载修改 在项目中直接新建一个单文件页,复制一下代码即可       upload组件: <template> <div class="vue-uploader" ...

  4. JS调用webservice服务

    webservice服务 webservice服务代码 using System; using System.Collections.Generic; using System.Linq; using ...

  5. Android 音视频深入 八 小视频录制(附源码下载)

    本篇项目地址,求starthttps://github.com/979451341/Audio-and-video-learning-materials/tree/master/%E5%B0%8F%E ...

  6. C#Mvc地址栏传值

    A页面 location.href = "/Home/Bpage?names=" +names; B页面 var loc = location.href;var n1 = loc. ...

  7. 开机出错提示 cpu fan speed error detected

    问题:开机跳 cpu fan speed error detected 分析:提示是cpu fan speed 有问题进入 BIOS 设置了好几次仍不行 解决方法: 进入BIOS,BOOT选项卡,将 ...

  8. @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 注解的作用

    在学习boot 项目的时候 ,发现在启动类中有一个这个的注解 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) ...

  9. ubuntu1604使用之旅——软件源更新(vim安装)

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup sudo gedit /etc/apt/sources.list # deb cd ...

  10. Linux磁盘格式化

    CentOS7所支持的文件系统格式:默认是用xfs作为系统的文件系统. "/"和"/boot"都是xfs格式! [root@linux-xl ~]# cat / ...