找回密码
 立即注册
首页 业界区 业界 一文入门 Android NDK 开发

一文入门 Android NDK 开发

赏勿 5 天前
SDK 与 API版本

Android build 中的 Java 版本 - https://developer.android.google.cn/build/jdks?hl=zh_cn
平台代号、版本、API 级别和 NDK 版本 - https://source.android.google.cn/docs/setup/about/build-numbers?hl=zh-cn#platform-code-names-versions-api-levels-and-ndk-releases
维基百科 Android - https://zh.wikipedia.org/wiki/Android
名称版本号API等级发行日期安全性更新状态Android 1.01.012008年9月23日不支持Android 1.11.122009年2月9日不支持Android Cupcake1.532009年4月27日不支持Android Donut1.642009年9月15日不支持Android Eclair2.0 – 2.15 – 72009年10月26日不支持Android Froyo2.2 – 2.2.382010年5月20日不支持Android Gingerbread2.3 – 2.3.79 – 102010年12月6日不支持Android Honeycomb3.0 – 3.2.611 – 132011年2月22日不支持Android Ice Cream Sandwich4.0 – 4.0.414 – 152011年10月18日不支持Android Jelly Bean4.1 – 4.3.116 – 182012年7月9日不支持Android KitKat4.4 – 4.4.419 – 202013年10月31日不支持Android Lollipop5.0 – 5.1.121 – 222014年11月12日不支持Android Marshmallow6.0 – 6.0.1232015年10月5日不支持Android Nougat7.0 – 7.1.224 – 252016年8月22日不支持Android Oreo8.0 – 8.126 – 272017年8月21日不支持Android Pie9282018年8月6日不支持Android 1010292019年9月3日不支持Android 1111302020年9月8日不支持Android 1212 – 12L31–322021年10月4日不支持Android 1313332022年8月15日支持Android 1414342023年10月4日支持Android 1515352024年10月15日支持Android 1616362025年6月10日支持

  • 关于ABI ( Application Binary Interface) 说明
ABI 名称对应 CPUarm64-v8a表示第 8 代 64 位 ARM 处理器armeabi-v7a表示第 7 代及以上 32 位 ARM 处理器armeabi表示第 5 代和第 6 代 32 位 ARM 处理器x86-64表示 Intel 64 位处理器(主要平板和虚拟机使用)x86表示 Intel 32 位处理器(主要平板和虚拟机使用)Gradlex SDK 版本配置

https://developer.android.google.cn/ndk/guides/sdk-versions?hl=zh_cn
compileSdkVersion

需要强调的是 修改 compileSdkVersion 不会改变运行时的行为 。当你修改了 compileSdkVersion 的时候,可能会出现新的编译警告、编译错误,但新的 compileSdkVersion 不会被包含到 APK 中:它纯粹只是在编译的时候使用。(你真的应该修复这些警告,他们的出现一定是有原因的)
因此我们强烈推荐 总是使用最新的 SDK 进行编译 。
minSdkVersion

定义应用程序支持的最低API版本
targetSdkVersion

targetSdkVersion 是 Android 提供向前兼容的主要依据
一个targetSdkVersion的属性值表示创建的Android项目使用哪个API版本,一个API版本使用一个整型数字表示,API的全称是Application Programming Interface,即应用程序编程接口,API 19对应的编程接口和API 23定义的编程接口存在差别,因为使用整型数字表示targetSdkVersion的属性值,容易记忆和便于比较它们之间的大小,高版本API编程接口可以兼容低版本API编程接口,反之则不行。
一个 NDK 调用示例

参考 [[N_Cmake]]
CMakeLists.txt
  1. # For more information about using CMake with Android Studio, read the
  2. # documentation: https://d.android.com/studio/projects/add-native-code.html.
  3. # For more examples on how to use CMake, see https://github.com/android/ndk-samples.
  4. # Sets the minimum CMake version required for this project.
  5. cmake_minimum_required(VERSION 3.22.1)
  6. # Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
  7. # Since this is the top level CMakeLists.txt, the project name is also accessible
  8. # with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
  9. # build script scope).
  10. project("pathplaning")
  11. # 设置 C++ 标准和相关标志
  12. set(CMAKE_CXX_STANDARD 14)
  13. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  14. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Wall -Wextra")
  15. #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
  16. # boost_1_74_0 和 rapidjson 都是包含头文件就能用
  17. set(BOOST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/boost_1_74_0)
  18. set(RAPIDJSON_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/rapidjson)
  19. # 设置头文件目录
  20. include_directories(
  21.         ${BOOST_ROOT}
  22.         ${RAPIDJSON_ROOT}
  23. )
  24. # 生成 静态库、动态库或对象库
  25. add_library(${CMAKE_PROJECT_NAME} SHARED
  26.         pathplan/canvas.cpp
  27.         pathplan/dubins.cpp
  28.         pathplan/line.cpp
  29.         pathplan/point.cpp
  30.         pathplan/polygon.cpp
  31.         pathplan/MainWindow.cpp
  32.         android_interface.cpp)
  33. # 链接库和依赖项
  34. target_link_libraries(${CMAKE_PROJECT_NAME}
  35.         android
  36.         log)
复制代码
主要在

  • include_directories 设置头文件的目录
  • add_library 这项目的目标;  生成静态库或动态库, 这里是 SHARED 动态库
  • target_link_libraries 链接 android 和  log
android_interface.cpp

注意函数名是有规则的 Java_{包名}_{类名}_{函数名}
  1. #include <jni.h>
  2. #include <string>
  3. #include "rapidjson/document.h"
  4. #include "rapidjson/stringbuffer.h"
  5. #include "rapidjson/writer.h"
  6. #include <boost/date_time/gregorian/gregorian.hpp>
  7. #include <boost/multiprecision/number.hpp>
  8. #include "pathplan/MainWindow.h"
  9. extern "C"
  10. JNIEXPORT jstring JNICALL
  11. Java_org_yang_web_action_PathAction_planning(JNIEnv *env, jobject thiz, jstring input) {
  12.     const char* p_input_char = env->GetStringUTFChars(input, nullptr);
  13.     rapidjson::Document doc;
  14.     doc.Parse(p_input_char);
  15.     if(doc.HasParseError()) {
  16.         env->ReleaseStringUTFChars(input, p_input_char);
  17.         return env->NewStringUTF("{"msg": "Parse Error"}");
  18.     }
  19.     // 如果 MW.path_obs 为空
  20.     rapidjson::Document output;
  21.     //空字符串
  22.     std::string obs_path_area = doc["obs_path_area"].GetString();
  23.     if(obs_path_area.empty() || obs_path_area.size() < 20) {
  24.         //无障碍规划
  25.         output = Single_Machine_Planner_Without_Obstacle_path_planner(doc);
  26.     }else{
  27.         output = Single_Machine_Planner_With_Obstacle_path_planner(doc);
  28.     }
  29.     auto inputString = std::string(p_input_char);
  30.     // 序列化 Document 为字符串
  31.     rapidjson::StringBuffer buffer;
  32.     rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  33.     output.Accept(writer);
  34.     std::string outputString = buffer.GetString();
  35.     //
  36.     env->ReleaseStringUTFChars(input, p_input_char);//释放
  37.     std::string message = "planning: input = " + inputString + ", output = " + outputString;
  38.     std::cout << message << std::endl;
  39.     return env->NewStringUTF(outputString.c_str());//返回字符串
  40. }
复制代码
全局引用

关于 gJniHelperInstance = env->NewGlobalRef(thiz); 在 JNI 中,默认传递的参数是​​局部引用​​:

  • 局部引用只在当前 JNI 函数调用期间有效
  • 当 JNI 函数返回时,局部引用会自动失效
  • 如果尝试在后续调用中使用局部引用,会导致崩溃或未定义行为
  1. package org.yang.njzj.web.action
  2. import android.content.Intent
  3. import org.yang.njzj.activity.QRCodeActivity
  4. import org.yang.njzj.utils.JacksonUtils
  5. import org.yang.njzj.web.WebActivity
  6. import org.yang.njzj.web.dto.InteractiveMessage
  7. import org.yang.njzj.web.inter.CoroutinesProcess
  8. import org.yang.njzj.web.js.WebInteractiveMediation
  9. import pub.devrel.easypermissions.EasyPermissions
  10. import pub.devrel.easypermissions.PermissionRequest
  11. import java.util.Map
  12. /**
  13. * @description
  14. */
  15. class PathAction(private val wim: WebInteractiveMediation): CoroutinesProcess<InteractiveMessage> {
  16. //  区域规划算法模块
  17.     companion object {
  18.         init {
  19.             System.loadLibrary("pathplaning")
  20.         }
  21.     }
  22.     external fun planning(paths: String): String
  23. }
复制代码
调用入口
  1. plugins {
  2.     id("com.android.application")
  3.     id("org.jetbrains.kotlin.android")
  4.     id("com.google.devtools.ksp")
  5. }
  6. android {
  7.     namespace = "org.yang.njzj"
  8.     compileSdk = 35
  9.     defaultConfig {
  10.         applicationId = "org.yang.njzj"
  11.         minSdk = 29
  12.         targetSdk = 34
  13.         versionCode = 1
  14.         versionName = "1.3.7"
  15.         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
  16.         vectorDrawables {
  17.             useSupportLibrary = true
  18.         }
  19.         ndk {
  20. //         ABI 过滤
  21. //            abiFilters.addAll(listOf( "arm64-v8a","armeabi-v7a", "x86_64", "x86"))
  22.             abiFilters.addAll(listOf( "arm64-v8a", "x86_64"))
  23.         }
  24.         externalNativeBuild {
  25.             cmake {
  26.                 cppFlags += ""
  27.                 arguments += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON"
  28.             }
  29.         }
  30.     }
  31. ....
  32. //    NDK
  33.     externalNativeBuild {
  34.         cmake {
  35.             path = file("src/main/cpp/CMakeLists.txt")
  36.             version = "3.22.1"
  37.         }
  38.     }
  39. }
  40. dependencies {
  41.   
  42. }
复制代码
关于 Android.mk

https://developer.android.com/ndk/guides/android_mk?hl=zh-cn
​Android.mk​​ 是 Android 构建系统中用于编译 ​​本地代码(C/C++)​​ 的配置文件。它基于 GNU Make 语法,主要用于定义如何编译 JNI 库(.so文件)、可执行文件或静态库(.a)。
Android.mk 文件位于项目 jni/ 目录的子目录中,用于向构建系统描述源文件和共享库。它实际上是一个微小的 GNU makefile 片段,构建系统会将其解析一次或多次。Android.mk 文件用于定义 Application.mk、构建系统和环境变量所未定义的项目级设置。它还可替换特定模块的项目级设置。
in short 类似 CMakeLists 的一个定义文件 管理编译本地代码库的, 新项目建议优先使用 ​​CMake​​(CMakeLists.txt) 不学也罢

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

5 天前

举报

5 天前

举报

前天 02:03

举报

您需要登录后才可以回帖 登录 | 立即注册