AndroidStudio 开发JNI
Android版本不断更新,发现网上很多JNI的教程,都不太适用了,会遇到各种问题,今天自己来总结一个。
NDK下载
我们下载NDK,有两种下载方式:
- 这是Google官方下载 点击下载NDK;
通过SDK Manger下载

点击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的更多相关文章
- AndroidStudio开发工具快捷键
在这里,自己整理了下在使用AndroidStudio开发工具所使用到的一些快捷键提示,也出于在开发过程中节省时间提升效率,然而可能多数开发者之前使用的都是Eclipse开发工具,可能开始都不习惯,但是 ...
- NDK工具开发Jni,Android studio jni开发
NDK工具开发JNI 对于JNI的作用,我这边就不详细说明了,百度google 有很多这样的介绍,这边着重详解AS使用NDK工具开发,调C的流程. 1,创建工程 2,创建native方法 //该类的路 ...
- Android NDK开发 JNI操作java构造方法,普通方法,静态方法(七)
Android NDK开发 JNI操作java普通.静态.构造方法 1.Jni实例化一个Java类的实例jobject 1.通过FindClas( ),获取Java类的的jclass 2.通过GetM ...
- c++ 开发JNI
c++ 开发JNI C的预处理命令 #开头的就是c/c++的预处理命令 在编译之前 先会走预编译阶段 预编译阶段的作用就是 把 include进来的头文件 copy到源文件中 define这些宏定义 ...
- Android-studio开发 快捷键
这会儿正在学android开发,使用的是Android-studio 记录一下开发工具默认的 快捷键
- Android Studio开发JNI工程
转:http://www.2cto.com/kf/201412/361768.html 使用Android Sutdio创建一个新的工程后,接下来记录创建NDK工程的基本步骤. 本文将达到: 1. 创 ...
- Android Studio NDK开发-JNI调用Java方法
相对于NDK来说SDK里面有更多API可以调用,有时候我们在做NDK开发的时候,需要在JNI直接Java中的方法和变量,比如callback,系统信息等.... 如何在JNI中调用Java方法呢?就需 ...
- 使用Android-studio开发移动app与weex结合开发详细步骤
详细步骤如下: 首先,确保机器已经安装了node.js,并且把npm更新到最新版本 下载完毕后,我们可以看到全局目录下的node_modules下面多出一个weex-toolkit 同时,我们留意 ...
- Android4.2.2NDK和源代码开发jni的异同
C/C++开发,在NDK和源代码中输出Log信息的方法! NDK: 1.包括头文件 #include <android/log.h> 2.Android.mk中包括库 LOCAL_LDLI ...
随机推荐
- WPF InkCanvas 书写毛笔效果
https://www.cnblogs.com/younShieh/p/10602787.html
- Matlab:显(隐)式Euler和Richardson外推法变步长求解刚性问题
一.显示Euler 函数文件:Euler.m function f=Euler(h,Y) f(1,1)=Y(1)+h*(0.01-(1+(Y(1)+1000)*(Y(1)+1))*(0.01+Y(1) ...
- 【其他】【http】【1】HTTP状态码
一些常见的状态码: 200 - 服务器成功返回网页 400 - 错误请求 404 - 请求的网页不存在 500 - 服务器内部错误 503 - 服务器超时 状态码大全: 1xx(临时响应)表示临时响应 ...
- CI集成 mesos 资源分配的思考, 待续
读了mesos的论文(https://people.eecs.berkeley.edu/~alig/papers/mesos.pdf ),感觉应用在 CI 上的资源管理很赞,能够解决 jenkins在 ...
- 索引(B-树)
前言 本文是在讲述什么样的数据结构适合作为索引,以及其适合作为索引的原因.而阅读本文需要对B树和B+树结构有稍微的理解.以及需要对磁盘操作知识有稍微的了解.对于磁盘操作的相关知识,在文章尾部的链接文章 ...
- STL 小白学习(2) string
#include <iostream> using namespace std; #include <string> //初始化操作 void test01() { //初始化 ...
- MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example 1.4 Labeling the Map
MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example 1.4 Labeling the Map 一.前言 MapServer拥有非常灵活的标签 ...
- UVa LA 4254 - Processor 二分,贪心 难度: 1
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- LeetCode 总结,二叉树各种类型问题小结
三大遍历 前序遍历 中序遍历 后序遍历 关于三大基础遍历,必须要条件反射式的记住:三种遍历的迭代方式使用的都是栈,后序遍历必须使用了 两个栈,其余乱七八糟的解决方式统统就不要再记了. 广度遍历: 分析 ...
- HTML5:图片、音乐和视频
图片.音乐和视频 一.图片 1.属性 属性 说明 alt 规定图像的替代文本. src 规定显示图像的 URL align 规定如何根据周围的文本来排列图像. border 定义图像周围的边框. he ...