Android扩展知识 - so文件生成及其使用

前言:想借助JNI和NDK的知识开发Android的串口通信,但是之前对这一部分没有了解过,以至于第一步so文件的生成和使用,就花费了两天,这里记录下配置过程。(网上有些资料也不完全对,走了很多弯路。)
借鉴博客如下:

https://blog.csdn.net/doris_d/article/details/53330838?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.pc_relevant_default&utm_relevant_index=5

https://blog.csdn.net/u010976213/article/details/50816956?spm=1001.2014.3001.5506

Android Studio软件的配置说明

  • Android Studio Arctic Fox | 2020.3.1 Patch 2
  • distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
  • classpath "com.android.tools.build:gradle:7.0.2"
  • 以下工程就是正常新建工程得到的
  • 之所以提到版本号,是因为不同版本号操作步骤略有不同,这里只是给大家做参考。

NDK/JNI介绍

什么是NDK?

  • NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。NDK继承了交叉编译器(交叉编译器需要UNIX或LINUX系统环境),提供了响应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单地修改mk文件(指出”哪些文件需要编译“、“编译特性要求等”),就可以创建出so。

为什么使用NDK?

  • 代码的保护,由于apk的java代码层很容易被反编译,而C/C++库反汇难度较大。
  • 可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
  • 提高程序的执行效率,将要求高性能的应用逻辑使用C开发,从而提高程序的执行效率。
  • 便于移植,用C/C++写的库可以方便地在其他的嵌入式平台上再次使用。

什么是JNI?

  • JNI的全称是Java Native Interface ,它提供了若干的API实现了Java和其他语言的通信(主要是C/C++)。

为什么使用JNI?

  • JNI的目的是使java方法能够调用c实现的 一些函数。

安卓中的so文件是什么?

  • android中用到的so文件是一个c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹中供java调用。

NDK的安装及其配置

NDK的安装

  • 可以直接从Android Studio软件中的SDK Manager中:Settings — Appearance & Behavior — Android SDK

  • 选中SDK Tools
    在这里插入图片描述

  • 下载NDK和CMake,只需要勾选前面,点击OK即可下载。

  • 这里注意可以点击右下角的 Show Package Details,可以看到安装包的版本。
    在这里插入图片描述

  • 开始NDK和CMake我都选择了最新版本:NDK – 24.0.8215888 , CMake – 3.18.1
    在这里插入图片描述

  • 但是出现问题NDK does not contain any platforms,后来查阅资料知道,是因为NDK版本过高,不适合当前版本的Android Studio,因此又下载了较低版本的NDK和CMake,具体版本如上图所示。

  • 之前如果设置过SDK的下载路径,则NDK的下载路径会默认下载到SDK的下载路径里。等待10-15分钟左右,时间稍微有些长。

  • 但这里要注意下,Android Studio中的路径不要设置带空格和带中文的 ,我就是因为之前SDK的下载路径是带空格的,之前一直没出现问题,结果NDK的默认下载路径还是这个,但因为带空格,所以后面测试NDK是否配置成功时,一直不反应,无奈只能复制NDK和CMake的资料到另外新建的文件夹中(路径名不带空格)。

    • 原本下载路径是:D:\JAVA\tools\Android Studio\Android_Sdk
    • 将NDK和CMake单独复制出来的路径是:D:\JAVA\tools\AndroidSdk(其实由于我也不知道NDK和CMake的资料是哪几部分,索性把Android_Sdk中的内容全部复制到AndroidSdk文件夹中)
    • 大家如果路径不带空格和中文,就不用看我上面的废话,我只是做个笔记。

NDK的配置

  • 第一步:环境变量的配置
  • 电脑右键属性 – 高级系统设置 – 环境变量 – 系统变量(非用户变量)
    • 第一种方式:
      • 首先新建NDK_HOME 变量名,变量值是D:\JAVA\tools\AndroidSdk\ndk-bundle(不带空格) ,因为 ndk-bundle 文件夹中有 ndk-build 命令,因此需要设置。

      • 在这里插入图片描述

      • 编辑Path 环境变量,添加进 ndk-bundle 的路径,%NDK_HOME%

      • 在这里插入图片描述

    • 第二种方式:就是直接把 ndk-bundle 的路径添加进Path环境变量中,不需要在建立中间变量NDK_HOME。
    • 但我还是建议用第一种,因为NDK_HOME这个变量我们在使用终端命令时,是用得到的,即和JAVA_HOEM变量一样。
  • 第二步:Android Studio软件中配置 ndk-bundle 的路径,这里我写进的是带空格的路径,也不影响,但上面提到的Path环境变量里需要是不带空格的路径
    • 在这里插入图片描述
    • 我们一般是在SDK Location里直接选择 ndk-bundle 的路径即可,但我们这里显示灰色,无法选择,查阅资料,直接在 local.properties文件 中写进路径:
    • 在这里插入图片描述
  • 第三步:验证NDK配置是否成功:
    • 打开Android Studio的终端窗口:输入 ndk-build 命令行
    • 出现以下信息便证明配置成功
    • 在这里插入图片描述

so库开发

新建本地方法

  • 在MainActivity.java中建立了一个方法public native String getStrFromJNI();
  • 可以看到这个方法的声明中有 native 关键字,这个关键字表示这个方法是本地方法,也就是说这个方法getStrFromJNI()是通过本地代码(C/C++)实现的,在java代码中仅仅是声明。
  • 在这里插入图片描述

编译该类得到对应的.h文件

  • 进入终端命令窗口
  • 切换到java目录下:cd app\src\main\java
  • 再输入: javah -jni 包名.类名
  • 这里输入:javah -jni com.example.testndk2.MainActivity
  • 在这里插入图片描述
  • 编译成功后,等待会可以看到编译出的.h文件。
  • 在这里插入图片描述
  • 打开.h文件,其中最重要的代码是:
JNIEXPORT jstring JNICALL Java_com_example_testndk2_MainActivity_getStrFromJNI
  (JNIEnv *, jobject);
  • 其中遵循 Java_包名_类名_本地方法名 来定义。

创建jni文件夹,添加.c文件

  • 右键Moudle,菜单中选择 New -> Folder -> JNI Folder,弹出的对话框,直接点击完成。
  • 在这里插入图片描述
  • 将前面生成 .h文件 移到 jni 文件夹中
  • 再右键jni文件夹,弹出菜单选择New -> C/C++ Source File,创建demo.c文件。
  • 在这里插入图片描述
  • 在demo.c文件中编写测试代码:
#include <string.h>
#include <jni.h>

jstring
Java_com_example_testndk2_MainActivity_getStrFromJNI(JNIEnv *env,
                                                          jobject thiz) {
    return  (*env)->NewStringUTF(env, "I`m Str !");
}
  • 注意demo.c代码中的格式和.h文件中的相同:Java_包名_类名_本地方法名
  • 在这里插入图片描述

编写Android.mk文件

  • 右键 jni文件夹,弹出菜单 New -> File
  • 在这里插入图片描述
  • Android.mk 文件中编写代码
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE      :=   demo
LOCAL_SRC_FILES   :=   demo.c

include $(BUILD_SHARED_LIBRARY)
  • LOCAL_MODULE:=demo 是要生成的so库的名称,但实际为libdemo.so
  • LOCAL_SRC_FILES:=demo.c 是要使用的文件,刚才编写的demo.c文件
  • 注意这两句后面不要跟着注释,否则会报错Android NDK: LOCAL_MODULE definition in D:/JAVA/tools/AndroidSerialPort/TestNdk2/app/src/main/jni/Android.mk must not contain space
  • 接着在终端命令窗口中,在java目录下,输入指令:ndk-build
  • 接着窗口会打印出一系列信息:说明编译成功,生成.so文件。
  • 在这里插入图片描述
  • 等待会或者刷新工程,便看到工程目录中多出 libsobj 两个文件夹。
  • 在这里插入图片描述
  • libs文件夹中有四个子文件夹,每一个文件夹都有 libdemo.so文件 ,便是生成成功。

使用so文件

相关配置

  • 在app的 build.gradleandroid节点 下设置:
  • 在这里插入图片描述
    • 注意路径是libs文件夹的相对路径

MainActivity中引用libdemo.so和使用本地函数

在这里插入图片描述

注意

如果改变demo.c文件中代码内容,都需要重新ndk-build,重新编译生成.so文件。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android C 高级编程是指在Android开发中使用C语言进行高级编程的技术。而使用NDK(Native Development Kit)可以使开发者在Android应用中使用C/C++等本地语言进行编程。 NDK是一个工具集,它允许开发者在Android应用中嵌入本地代码,并且提供了一系列的开发工具和库,以便开发者能够在Android应用中使用C/C++进行高级编程。使用NDK可以提供更高的性能和更低的内存占用,适用于需要处理大量数据和高性能计算的应用场景。 在使用NDK进行Android C高级编程时,可以使用PDF(Portable Document Format)作为文档格式,以便对代码和项目进行更好的管理和文档化。在NDK的开发过程中,可以使用PDF文档记录关键的设计思路、代码逻辑、接口定义等信息,以方便团队协作和后续的维护。 使用NDK进行Android C高级编程的步骤大致如下: 1. 准备开发环境:安装NDK并配置好开发环境,包括设置NDK的路径和编译器等。 2. 创建新项目:使用Android Studio创建一个新的Android项目,并在项目中引入NDK的支持。 3. 编写C代码:使用C/C++语言编写需要调用的函数、算法或者数据结构等代码,并将其保存在适当的目录下。 4. 编写JNI接口:在生成的Java代码中,使用JNI(Java Native Interface)定义对应C代码的接口,以便在Java层调用C代码。 5. 编译和构建:使用NDK的工具集进行编译和构建,将C代码编译成适合Android平台使用的库文件(.so文件)。 6. 在Java代码中调用C代码:在需要调用C代码的地方,使用JNI接口调用对应的C函数,以实现和C代码的交互和调用。 使用PDF文档进行文档化可以帮助开发者更好地组织和管理代码、接口和设计文档等,方便后续的代码维护和项目协作。同时,也可以作为项目的参考文档,方便其他开发人员了解和使用项目。 ### 回答2: Android C 高级编程是针对使用NDK(Native Development Kit)的一种高级编程技术。NDKAndroid开发工具包中的一个工具,允许开发者使用C、C++或其他本地编程语言编写Android应用程序的部分或全部代码。 使用NDK进行Android C高级编程有许多优点。首先,NDK提供了更高的性能和更好的控制权,特别是在处理图形、音频和计算密集型任务时。通过使用本地编程语言,开发者能够更好地利用底层系统资源,提高应用程序的执行效率和速度。 其次,NDK还提供了对现有C和C++库的支持。这意味着开发者可以使用许多已经存在的库和功能来加快开发进程。无需重新编写现有的代码,直接使用NDK与这些库进行集成即可。 在使用NDK进行Android C高级编程时,一种常见的用途是开发游戏。使用C或C++编写游戏代码可以获得更好的性能和更低的延迟,这对于游戏的流畅运行至关重要。 此外,开发者还可以使用NDK为现有的Java应用程序添加本地本地扩展。这样可以通过使用C或C++编写某些关键组件,以改进应用程序的性能或添加新的功能。 总的来说,通过使用NDK进行Android C高级编程,开发者可以获得更高的性能、更好的控制权和更好的资源利用。无论是开发游戏还是优化应用程序,使用NDK都是提高性能和扩展功能的好方法。通过阅读相关的PDF文档,开发者可以更深入地了解如何使用NDK进行Android C高级编程。 ### 回答3: Android NDK (Native Development Kit) 是一个用于开发 Android 应用程序的工具集,它使开发者能够使用 C 或 C++ 编写原生代码,并将其与 Java 编写的 Android 应用程序一起使用使用 NDK 可以达到增加性能、复用现有的 C/C++ 代码以及访问底层硬件等目的。 在 Android C 高级编程中,使用 NDK 商用 PDF 库可以实现在 Android 应用程序中处理 PDF 文件的功能。PDF 文件是一种常见的电子文档格式,使用 PDF 库可以读取、编辑和生成 PDF 文件使用 NDK 进行 PDF 处理的一般步骤如下: 1. 集成 PDF 库:首先,需要将商用的 PDF 库 (.so 文件) 集成到 Android 项目中。可以通过在 Android.mk 文件中添加相关配置,确保 .so 文件正确地被编译和链接到应用程序中。 2. 创建 JNI 接口:为了在 Java 层与 C/C++ 层之间进行通信,需要创建 JNI (Java Native Interface) 接口。可以在创建 JNI 方法时使用 JNAerator 或者手动编写 JNI 代码,以便在 Java 层调用 C/C++ 的功能。 3. 对 PDF 文件进行处理:在 C/C++ 层,可以使用 PDF 库提供的功能来处理 PDF 文件。例如,可以使用库提供的函数来解析、渲染、添加标注、提取内容等。 4. 将数据返回给 Java 层:在 C/C++ 层处理完之后,可以通过 JNI 接口将处理后的数据返回给 Java 层。这样就可以在 Android 应用程序中显示或者存储处理后的 PDF 文件。 需要注意的是,在使用商用 PDF 库时,需要遵循相关的许可协议,并确保在开发和分发过程中合法使用该库。 总之,通过使用 NDK 和商用 PDF 库,可以使 Android 应用程序具有处理 PDF 文件的高级编程能力。同时,开发者需要具备 C/C++ 编程和 JNI 接口的使用经验,以便顺利地进行开发工作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值