一.介绍

  1.什么是ndk技术?

    在学习ndk技术前,我们需要先了解一下JNI(Java Native Interface)技术,JNI技术是一种实现Java代码和C/C++代码之间交互的技术,它提供了一组编程接口,使得Java程序可以调用C/C++代码并与其进行通信。通过JNI技术,开发者可以将C/C++代码嵌入Java项目中,并在Java代码中调用这些C/C++函数。那么,NDK技术和它有什么关系呢?NDK是一种用于开发Android应用程序的工具集,它允许开发者使用C/C++编写部分或全部的Android应用程序代码,以便提高性能和访问底层系统功能。这样看起来NDK技术和JNI技术是一回事,就是为了实现Java调用C/C++或C/C++调用Java。确实如此,用一句话概括它们之间的关系就是:开发者使用NDK技术在Android应用程序中编写C/C++代码,并将其编译成共享库(如.so文件),然后使用JNI技术在Java代码中加载并与这些C/C++代码进行交互。

  2.为什么要学习ndk?

    第一点的话就是提高性能了,这个显而易见,C/C++的性能肯定比Java高,如果有些功能用Java实现性能不行,就可以把这部分代码用C/C++实现。第二点的话就是C/C++语言可以直接访问底层系统功能和硬件资源,如摄像头和传感器等,这是Java做不到的。最后一点是保密性,Java代码是编译成字节码,而C/C++代码是直接编译成机器码,反编译的难度比Java大的多。所以,如果哪部分功能需要保密,也可以用C/C++来实现。

  3.编写C/C++代码并编译出.so文件

    我们要在Android项目中调用C/C++代码,首先要将写好的C/C++代码编译成.so共享库,下面我会以Android Studio 2021来详细讲解编译出.so文件的过程。

    第一步:打开Android Studio,新建一个Native C++项目,如下图所示:

   

    

    

    项目新建完成后是下面这个样子:

    

    我们可以看到main目录下面有一个cpp目录,这里就是我们编写C++代码的地方,我们先来看一下自动生成的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.18.1) //cmake的最低版本是3.18.1 # Declares and names the project. project("ndkstudy") # 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.
ndkstudy //生成的库的名称 # Sets the library as a shared library.
SHARED //设置生成的库为共享库.so # Provides a relative path to your source file(s).
native-lib.cpp //c++源文件的相对路径
) # 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) //使用find_library来查找log库,并把找到的log库存储在变量log-lib中 # 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.
ndkstudy # Links the target library to the log library
# included in the NDK.
${log-lib}) //将ndkstudy库和log库进行链接

    然后,我们再来看一下自动生成的native-lib.cpp文件,代码如下:

#include <jni.h>
#include <string> extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndkstudy_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}//函数的功能就是返回一个"Hello from C++"字符串

    我们发现这个函数名特别长,其实就是对应java目录下com.example.ndkstudy包下MainActivity类下的stringFromJNI()这个函数。了解了这些之后,我们只需要Make Project即可,如下图所示:    

    

    然后就可以看到所生成的.so文件了,如果没有的话,可以刷新一下项目  

    

    接下来,我们建一个新的项目,然后把上面所生成的不同CPU架构的.so文件复制到新项目的main/jniLibs目录,jniLibs目录需要自己新建。

    

    然后在app/build.gradle文件下添加以下的代码:

android {
namespace 'com.example.ndkstudy'
compileSdk 32 defaultConfig {
applicationId "com.example.ndkstudy"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
// 设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so)
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64"
}//新增代码
} buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
} dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

    接下来,就可以调用so库中的C++函数了,这里也是特别容易出错的地方,我先贴出代码,然后再详细讲解。

public class MainActivity extends AppCompatActivity {
private TextView tv_display;
{
System.loadLibrary("ndkstudy");//第一步,加载动态库,放到静态代码块里就行
} @SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_display=findViewById(R.id.tv_display);
tv_display.setText(stringFromJNI());//第三步,调用本地函数,实际上调用的函数是Java_com_example_ndkstudy_MainActivity_stringFromJNI();
} public native String stringFromJNI();//第二步,本地方法声明,也就是说这个方法由c++实现,这里作个声明 }

    一个特别需要注意的点是我们在加载动态库和作本地方法声明的时候,需要在com.example.ndkstudy包下,MainActivity类下进行操作,也就是要对应那个特别长的函数名。如果以上的步骤都没有错的话,就可以在手机屏幕上看到输出的"Hello from C++"字符串了。


    

  

Android进阶-NDK技术的更多相关文章

  1. Android的NDK技术

    Android的NDK技术

  2. 《Android进阶》之第七篇 NDK的使用

    <Android进阶>之第一篇 在Java中调用C库函数 这一篇列举的方法是在NDK没有出来时候用的方式 在Android发布NDK之后,可以这样使用 一.首先下载android-ndk ...

  3. Android开发面试经——4.常见Android进阶笔试题(更新中...)

      Android开发(29)  版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客:http:/ ...

  4. 我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!

    本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超 ...

  5. Android进阶推荐书籍

    中级进阶推荐看一下以下这几本书 1.<Android从入门到精通(附光盘)> 明日科技 编 2.<第一行代码2 Android(第二版)> 郭霖 著 3.<Android ...

  6. 这是一份非常适合收藏的Android进阶/面试重难点整理

    写在前面 记得我大二时“不务正业”地自学Android并跟了老师做项目,到大三开始在目前的公司实习,至今毕业已有几年多,学习Android已经6.7年多了!但总感觉知识点很零散,并且不够深入,遇到瓶颈 ...

  7. 可怕!字节跳动大牛爆出的“Android进阶指南”,强到无法形容,GitHub已标星“8.5k”!

    前言 从去年8月份开始,我开始重新找工作,在这期间刷了不少面试题和大牛博客,无意中薅到一份字节跳动大牛整理的一份"Android进阶指南",包含Android面试常见问题.主流技术 ...

  8. Android之NDK开发(转)

    Android之NDK开发 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  9. Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

  10. Android之NDK开发

    转自:http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html 一.NDK产生的背景 Android平台从诞生起,就已经支持C ...

随机推荐

  1. Django相关配置信息

    Django相关配置信息 1.配置数据库mysql 1.1 setting.py中配置信息 DATABASES = { 'default': { 'ENGINE': 'django.db.backen ...

  2. Docker容器核心实践(操作容器)

    镜像和容器是docker中最基础的概念,镜像可以理解为包含应用程序以及其相关依赖的一个基础文件系统,在其启动过程中,以只读的方式被用于创建容器的运行环境,本质上是基于UnionFS文件系统的一组镜像层 ...

  3. Yapi及Swgger使用+注解

    1.Yapi 1.1 介绍 YApi 是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测试人员提供更优雅的接口管理服务.可以帮助开发者轻松创建.发布.维护 API,YApi 还为用户提供 ...

  4. itext 生成pdf ----hello world

      iText是Java中用于创建和操作PDF文件的开源库.它是由Bruno Lowagie.Paulo Soares等人编写的.Ohloh报告称2001年以来[2],26个不同的贡献者进行了1万多次 ...

  5. [C++提高编程] 1、模板

    文章目录 1 模板 1.1 模板的概念 1.2 函数模板 1.2.1 函数模板语法 1.2.2 函数模板注意事项 1.2.3 函数模板案例 1.2.4 普通函数与函数模板的区别 1.2.5 普通函数与 ...

  6. pip 国内源地址

    1.使用方式 pip install 包名 -i 国内源地址 2.国内源地址 豆瓣(douban)  http://pypi.douban.com/simple/ 清华大学 https://pypi. ...

  7. day09-达人探店

    功能04-达人探店 5.功能04-达人探店 5.1发布&查看探店笔记 5.1.1发布探店笔记 探店笔记类似点评网站的评价,往往是图文结合.对应的表有两个: tb_blog:探店笔记表,包含笔记 ...

  8. 可视化—gojs 超多超实用经验分享(一)

    目录 1. 设置分组模板,默认样式,统一最小宽度,展开收起状态监听 2. 分组名称显示成员个数: 分组名称+成员个数: name(children) 3. 分组成员为空时,不显示 placeholde ...

  9. 高精度地形DEM数据下载(NASA数据 12.5米分辨率)

    本文介绍从NASA阿拉斯加卫星设备处网站下载高精度DEM数据,下载的数据精度是12.5米分辨率. 目前国内大部分可以下载的dem数据都是30米或90米分辨率的,对于更高精度的数据要不就是需要付费下载, ...

  10. Prism Sample 2

    例2引入了Region的概念. 例1中我们提到bootstrapper与app.xaml.cs,现在是这样的: public partial class App : PrismApplication ...