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 ...
随机推荐
- 关于IDEA每次修改HTML,Css等静态资源文件都需要重启的设置修改
~ ~ ~ ~ ~ 关于IDEA每次修改HTML,Css等静态资源文件都需要重启的设置修改 最近开始使用IDEA进行项目开发,但是对于每次修改HTML文件中css和js文件之后都必须重启服务这件事表示 ...
- System.Web.WebPages.Html.HtmlHelper”不包含XXXX
1.关闭Visual Studio中 2.删除bin和OBJ文件夹 3.重新打开您的解决方案
- lumion的基本操作,天气系统,景观系统。5.25
1.打开场景,按住鼠标右键可以选择方向. 2.向前移动:W,向后移动S,亦可以用鼠标滚轮向前或者向后滚.向左A向右D, 3.Q提升视角,E下降视角. 4.鼠标滚轮点下去,进行提升和下降视角.左右移动, ...
- CCF关于NOIP竞赛程序提交的管理规则
在NOIP复赛中,NOI各省组织单位必须严格遵循CCF<关于NOIP数据提交格式的说明>的规范在竞赛结束后规定时间内向CCF提交本赛区所有参赛选手的程序. 为竞赛的公平以及赛后按时完成竞赛 ...
- CodeForces - 1015 D.Walking Between Houses
Description Natasha is planning an expedition to Mars for nn people. One of the important tasks is t ...
- Java数组声明、初始化
维数组的声明方式:type var[]; 或type[] var; 声明数组时不能指定其长度(数组中元素的个数), Java中使用关键字new创建数组对象,格式为:数组名 = new 数组元素的类型 ...
- vue-router进阶-1-导航守卫
导航守卫主要用来通过跳转或取消的方式守卫导航 全局守卫,使用 router.beforeEach 注册一个全局前置守卫 const router = new VueRouter({ ... }) ro ...
- Problem B: 平面上的点和线——Point类、Line类 (II)
Description 在数学上,平面直角坐标系上的点用X轴和Y轴上的两个坐标值唯一确定,两点确定一条线段.现在我们封装一个“Point类”和“Line类”来实现平面上的点的操作. 根据“append ...
- Core Json 序列化相关问题
//返回json 大小写 配置 services.AddMvc() .AddJsonOptions( op => op.Serial ...
- 马凯军201771010116《面向对象程序设计(java)》第二周学习总结
第一部分:理论知识学习部分 (1)基本知识:简单应用程序的结构:Java环境里的注释方式: (2)数据类型(4种整型.2种浮点型.1种字符型‘char’.真值型‘Boolean’. (3)变量,每个变 ...