android串口开发入门之搭建ndk开发环境及第一个jni调用程序
作者:喝着啤酒写bug 发布时间:2023-03-14 16:54:55
前言
这几天专门研究了下JNI编程,在网上找了好多资料,不过好多都是以前的,没有更新,而且有的还是错误的,让人不得不吐槽一把。所以觉得自己来一篇,本文将详细介绍关于android搭建ndk开发环境及第一个jni调用程序的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
一:ndk环境搭建
1:开发环境
我使用的是android studio 2.3.3版本,搭建ndk开发环境比较简单,打开File----Settings----Appearance&Behavior----System Settings----Android SDK,选择SDK Tools,将CMake,LLDB,NDK 前的复选框勾上,点击Apply,然后就是等待ndk下载完成。
安装成功后,右键项目----open module setting,Android NDK location会自动赋值
二:第一个jni程序
1:创建ndk项目
创建ndk项目和普通android项目有一点区别,需要把Include C++ support前面的复选框勾上,然后直接下一步。但在最后一步,有一个c++下拉框选项,可以根据你的实际情况适当修改,C++ Standard :点击下拉框,可以选择标准 C++,或者选择默认 CMake 设置的 Toolchain Default 选项。Exceptions Support :如果你想使用有关 C++ 异常处理的支持,就勾选它。勾选之后,Android Studio 会在 module 层的 build.gradle 文件中的 cppFlags 中添加 -fexcetions 标志。Runtime Type Information Support :如果你想支持 RTTI,那么就勾选它。勾选之后,Android Studio 会在 module 层的 build.gradle 文件中的 cppFlags 中添加 -frtti 标志。
项目创建好后,app下多了一个cpp目录,该目录用于存放c程序的源码,头文件,预编译项目等,android studio 会默认帮我们创建一个native-lib.cpp文件,该文件已有一个测试方法,结构图如下:
通过上图看到,在External Build Files 下面多了一个CMakeLists.txt文件,该文件用于c程序需要生成so文件的配置文件。
cmake_minimum_required(VERSION 3.4.1):这是版本信息,我们不用管它
add_library():这个命令是,通过add.library()定义多个库,CMake会去自动构建他们,一个*.cpp文件对应一个add_library命令.
add_library( # Sets the name of the library.生成so文件的名字,建议和cpp文件同名
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s). 需要生成so文件的cpp文件名称
src/main/cpp/native-lib.cpp )
find_library():定位 NDK library 的位置,并将其位置存储在一个变量之中。在构建脚本的其他地方使用这个变量,来代指 NDK library。下面的示例代码将 Android-specific log support library 的位置存储到变量 log-lib 中
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
现在我们来看native-lib.cpp文件,这是as帮我们自动生成好的,返回是一个Hello from C++的字符串。
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
JNIEXPORT jstring JNICALL 这里的jstring代表返回值, 参数JNIEnv* env,代表指针,jobject 代表调用这个方法的对像(普通方法是jobject,静态方法是jclass)后面的参数和java类中定义的本地方法对数相对应,方法命名规则:Java_包名_调用jni方法的类名_方法名,android studio 帮我们生成的程序,activity包名是serialport.com.ndkjnidemo,类名是MainActivity,方法名是stringFromJNI,所以native-lib.cpp方法名称为Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI,其中返回值类型和java数据类型对应如下
如果我们需要写多个jni方法,*.cpp格式如下:
//方法一
extern "C"
JNIEXPORT jstring JNICALL
Java_serialport_com_ndkjnidemo_MainActivity_test1(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
//方法二
extern "C"//如果不写extern "C" java是无法调用到这里定义的方法
JNIEXPORT jstring JNICALL
Java_serialport_com_ndkjnidemo_MainActivity_test2(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
最后我们来看自动生成的MainActivity,在onCreate中调用stringFromJNI,然后给文本组件赋值,软件运行参见图一
package serialport.com.ndkjnidemo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity {
static {//native-lib值来自,CMakeLists.txt文件中,add_library命令的第一个参数
System.loadLibrary("native-lib");
}
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.sample_text); tv.setText(stringFromJNI());}public native String stringFromJNI();
}
代码都是android studio自动自成的,所以此处不上传代码,demo运行结果:
参考文章:
Android NDK 开发(五)AndroidStudio 2.2 NDK的开发环境搭建
一天掌握Android JNI本地编程 快速入门
来源:https://www.cnblogs.com/cq-jiang/p/8145281.html


猜你喜欢
- 动态SQL实现前端指定返回字段问题描述在使用ClickHouse时,遇到需要根据业务需求,动态返回指定字段,从而充分利用ClickHouse
- 目录获取程序下面的文件获取临时目录下的文件获取程序下面的文件首先我们创建了实例解决方案:其中调用链是:Main.Shell->FooA
- 前言Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据
- 在开发Web办公系统或文档系统时,PageOffice组件是众所周知的在线处理微软word/ppt/excel文档的强大工具,它对WORD文
- 将图片上传到webapp路径下 路径获取方式此方法获取到工程webapp文件夹下String contexPath= request.get
- 了解了inbound事件的传播过程, 对于学习outbound事件传输的流程, 也不会太困难outbound事件传输流程在我们业务代码中,
- 碎片,它的出现是为了更好展示UI的设计,让程序更加得到充分的展示。Fragment的出现,如微信的额主界面包含多个Fragment,使得微信
- 本文主要给大家分享如何在全局上去监听 click 点击事件,并做些通用处理或是拦截。使用场景可能就是具体的全局防快速重复点击,或是通用打点分
- 在我们对gc中的算法有基本概念理解后,要把算法的理念实现还需要依托实际垃圾收集器的使用。因为光靠一些简单的原理不足以支撑整个程序的运行,在回
- 布局:<?xml version="1.0" encoding="utf-8"?><
- 在java项目开发中。最开始换行符大家一般是在idea中设置新文件为LF,并且对旧文件通过IDEA下方的点击来更换换行符。很显然,对于几千文
- 本文实例讲述了C#实现百分比转小数的方法。分享给大家供大家参考。具体分析如下:近日需要用到百分比转小数功能,而且百分比是字符串格式(可以带或
- 本文实例讲述了C#中winform控制textbox输入只能为数字的方法。分享给大家供大家参考。具体实现方法如下:添加keyPress事件,
- 最近看了一些淘宝购物车的demo,于是也写了一个。效果图如下:主要代码如下: actvity中的代码:public class Shoppi
- 本文实例为大家分享了java实现微信扫码支付的具体代码,供大家参考,具体内容如下1、maven项目的pom.xml中添加如下jar包:<
- 在我们对数组或者集合类进行操作的时候,经常会遇到这样的需求,比如:是否包含某一个“匹配规则”的元素是
- 迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。只要拿到这个对象
- 需求分析:我们在做winform开发的时候,有时候需要让程序休眠几秒钟,但是如果我们直接使用 Thread.Sleep()函数的话,页面UI
- springboot获取项目目录路径springboot部署后获取项目的路径//获取跟目录(绝对路径)File path = new Fil
- 前言将采用slf+log4j2方式进行打印日志,以下用两种方式,一种基于maven的springboot2,一种jdk6,普通jar包的sp