一: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本地编程 快速入门

  

android 串口开发第一篇:搭建ndk开发环境以及第一个jni调用程序的更多相关文章

  1. iOS开发——高级技术精选&底层开发之越狱开发第一篇

    底层开发之越狱开发第一篇 做越狱开发也有一些时间了,有很多东西想总结一下,希望给他人一些借鉴,也是自己对过去开发经历的一些总结.个人不推荐使用盗版,这里主要以技术介绍为主. 这个系列里面主要介绍怎样进 ...

  2. Android JNI和NDK学习(01)--搭建NDK开发环境(转)

    本文转自:http://www.cnblogs.com/skywang12345/archive/2013/05/23/3095013.html 本文主要介绍“JNI”.“Android NDK”以及 ...

  3. vue+uni-app商城实战 | 第一篇:【有来小店】微信小程序快速开发接入Spring Cloud OAuth2认证中心完成授权登录

    一. 前言 本篇通过实战来讲述如何使用uni-app快速进行商城微信小程序的开发以及小程序如何接入后台Spring Cloud微服务. 有来商城 youlai-mall 项目是一套全栈商城系统,技术栈 ...

  4. iOS开发网络篇—搭建本地服务器

    iOS开发网络篇—搭建本地服务器 一.简单说明 说明:提前下载好相关软件,且安装目录最好安装在全英文路径下.如果路径有中文名,那么可能会出现一些莫名其妙的问题. 提示:提前准备好的软件 apache- ...

  5. 第一章 搭建Qt开发环境

    第一章 搭建Qt开发环境 1.到http://download.qt-project.org/archive/上下载Qt的源码包.我下载的是qt-everywhere-opensource-src-4 ...

  6. 第一篇:打造专属开发工具Eclipse篇

    第一篇:打造专属开发工具Eclipse篇 eclipse 优化 1.动画很酷,但如果可以的话,我总是在所有的工具中禁用动画.所以classic或者window classic主题是我最常用的主题 , ...

  7. 第一篇 Windows 8 开发Windows Metro style app环境配置

    半   饱问 题 到 我 这 里 为 止! 第一篇 Windows 8 开发Windows Metro style app环境配置 2012-09-24 08:24 by 半饱, 1289 阅读, 3 ...

  8. Android开源项目第一篇——个性化控件(View)篇

    本文为那些不错的Android开源项目第一篇——个性化控件(View)篇,主要介绍Android上那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Ga ...

  9. AI应用开发实战 - 从零开始搭建macOS开发环境

    AI应用开发实战 - 从零开始搭建macOS开发环境 本视频配套的视频教程请访问:https://www.bilibili.com/video/av24368929/ 建议和反馈,请发送到 https ...

随机推荐

  1. angularJS的一些用法

    AngularJS 事件指令: ng-click/dblclick ng-mousedown/up ng-mouseenter/leave ng-mousemove/over/out ng-keydo ...

  2. 学习爬虫的day02 (用线程去爬虫 提高速度)

    通过lxml的方式去分析数据,将爬到的数据放到file中的html中代码如下# 用线程去爬虫 from urllib.request import Request from urllib.reques ...

  3. 【转】three.js详解之入门篇

    原文链接:https://www.cnblogs.com/shawn-xie/archive/2012/08/16/2642553.html   开场白 webGL可以让我们在canvas上实现3D效 ...

  4. accept 文件描述符用尽处理

    if (events[i].data.fd == listenfd) { peerlen = sizeof(peeraddr); connfd = ::accept4(listenfd, (struc ...

  5. Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

    很多时候前端都需要调用后台服务实现交互功能,常见的数据交换格式多是JSON或XML,这里主要讲解Spring MVC为前端提供JSON格式的数据并实现与前台交互.RESTful则是一种软件架构风格.设 ...

  6. 分享一小坑(与swagger有关),以后碰到了可以快速规避

     ---------------------------------------------------------------------------------踩坑过程:①webapi的某acti ...

  7. 深入解析Java垃圾回收机制

    引入垃圾回收 哪些内存需要回收? 引用计数法 可达性分析 如何回收 Marking 标记 Normal Deletion 清除 Deletion with Compacting 压缩 为什么需要分代收 ...

  8. Java调用PDFBox打印自定义纸张PDF

    打印对象 一份设置为A3纸张, 页面边距为(10, 10, 10, 10)mm的PDF文件. PageFormat 默认PDFPrintable无法设置页面大小. PDFPrintable print ...

  9. 【luogu P1613】跑路

    https://www.luogu.org/problem/show?pid=1613 看到2k就能想到倍增.用一个数组avai[i][j][k]表示点i与点j是否存在长2k的路径,则可以递推出ava ...

  10. Java SE 8 流库(二)

    1.3. filter,map,flatMAP方法 流的转换会产生一个新流,它的元素派生出自另一个流中的元素: Stream<T> filter(Predicate<? super ...