android+jni和ndk区别,Android JNI和NDK学习(一):NDK学习

概述

想要学习JNI和NDK,首先要知道JNI和NDK分别是什么,都有什么作用,这样才可以更好的学习和理解JNI和NDK,本篇文章主要作为学习笔记,以防以后忘记

JNI介绍

定义:JNI即 Java Native Interface java本地接口

作用:可以让java和其他类型语言(例如C和C++)进行交互

注意:JNI是属于java的,跟 android 没有关系

NDK 介绍

定义:NDK即 Native Development Kit 是一个android的一个开发工具包

作用:快速开发C/C++动态库,并自动把so和应用打包成APK

注意:NDK是属于android的和java无关

JNI和NDK的联系

可以通过NDK工具 在Android中使用JNI与本地代码(C、C++)进行交互

JNI是实现的目的,NDK是实现JNI的手段

即在Android 的开发环境中(Android Studio)通过NDK实现JNI的功能

复制代码

使用Android Studio 创建一个NDK项目

由于Android Studio2.2以上已经内部集成了NDK 所以只需要在Android Studio内部配置即可,我目前演示的版本为3.5.3

d853dccfcbd4afb8d3b5492650f95fab.png

24dd7db8eac9742427e822de05c05316.png

9a0420c835256bee9782112b594af411.png

经过这三个步骤就可以自动生成一个NDK项目

59f9b246e8fa8bfda560759c1b7c3122.png

和普通的项目相比多了这个文件夹,其中native-lib.cpp是C、C++代码,CMakelist.txt是编译脚本

下面分析下这个项目

MainActivity

public class MainActivity extends AppCompatActivity{

// Used to load the 'native-lib' library on application startup.

static {

System.loadLibrary("native-lib");

}

@Override

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// Example of a call to a native method

TextView tv = findViewById(R.id.sample_text);

tv.setText(stringFromJNI());

}

/**

* A native method that is implemented by the 'native-lib' native library,

* which is packaged with this application.

*/

public native String stringFromJNI();

}

复制代码

首先加载native-lib.so,然后调用so中的stringFromJNI方法,最后把这个方法返回的值显示在TextView上

其中native-lib.so,这个库的名称是在CMklist.txt中指定的, stringFromJNI是一个java中native方法,其真正的实现在native-lib.cpp中

native-lib.cpp

#include

#include

extern "C" JNIEXPORT jstring JNICALL

Java_com_text_ndk1_MainActivity_stringFromJNI(

JNIEnv *env,

jobject /* this */){

std::string hello = "Hello from C++";

return env->NewStringUTF(hello.c_str());

}

复制代码

上面的public native String stringFromJNI()的实现就是在这里,那么如何确定java中的Native方法对应C中的哪个方法呢,这里用的是静态注册,即Java包名类名_方法名的形式,后面再继续讲其他的注册方式

整个调用流程

Gradle调用外部构建脚本CMklist.txt

CMake按照脚本中的命令将C++源文件native-lib.cpp编译成native-lib.so动态库,并把它编译到APK中

运行时首先加载native-lib.so,然后调用so中的stringFromJNI方法,最后把这个方法返回的值显示在TextView上

配置Gradle支持NDK

我们先看下上面建立的项目的gradle

150d475ec48181873c899851f3a82bf2.png

其中里面红色框是配置NDK的,也就是说需要配置externalNativeBuild {}添加到gradle中,并使用 cmake {}进行配置

我们可以看到Gradle中俩个地方用了externalNativeBuild {},一个在defaultConfig里面一个在defaultConfig外面

在defaultConfig外面的externalNativeBuild {}代码块用cmake制定了CMakeList.txt的路径

在defaultConfig里面的externalNativeBuild {}代码块用cmake主要是填写CMake命令参数

CMakeLists.txt 文件分析

# For more information about using CMake with Android Studio, read the

# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC

# or SHARED, and provides the relative paths to its source code.

# You can define multiple libraries, and CMake builds them for you.

# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.

native-lib

# Sets the library as a shared library.

SHARED

# Provides a relative path to your source file(s).

native-lib.cpp)

# Searches for a specified prebuilt library and stores the path as a

# variable. Because CMake includes system libraries in the search path by

# default, you only need to specify the name of the public NDK library

# you want to add. CMake verifies that the library exists before

# completing its build.

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)

# Specifies libraries CMake should link to your target library. You

# can link multiple libraries, such as libraries you define in this

# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.

native-lib

# Links the target library to the log library

# included in the NDK.

${log-lib})

复制代码

cmake_minimum_required(VERSION 3.4.1)

设置CMake的最低版本

add_library

第一个参数:设置这个库的名字

第二个参数:设置库的类型,SHARE 动态库.so后缀 ,STATIC 静态库 .a后缀

第三个参数:源文件的相对路径

可以定义多个库,CMake会构建他们,Gradle将自动把共享库打入APK中

find_library

找到一个NDK库,并且把这个库的路径储存在一个变量中,例如例子中就是找到一个NDK中的log库(支持android的日志库),并且把变量储存在log-lib变量中

target_link_libraries

关联库,将指定的库关联起来,比如上边的例子,第一个参数:目标库,第二个参数:将目标库链接到日志库包含在NDK中。

这是一个最基础的CMakeLists.txt,其实他可以非常的强大,比如可以自定义命令,查找文件,设置变量等,推荐参考CMAKE手册

参考:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值