使用Android Studio开发Native应用

Android Studio NDK开发

一直以来,在开发Android应用的过程中,时常需要接触许多使用C/C++编写的开源库,传统方式之前都是在虚拟机中使用ubuntu环境,或者Android源码环境编译成库之后,再拷贝到应用中来引用。最近发现使用Android Studio来进行NDK开发还是挺方便的,在此总结一下日常工作过程中使用Android Studio开发native应用相关的一些常见知识点,帮助自己系统性的巩固该方面的知识点,全文大纲如下:

在这里插入图片描述

目录

  • Gradle文件配置
  • cmake常见语法
  • JNI的基本操作
  • 官方手册地址

Gradle文件配置

模块支持NDK,需要在build.gradle中配置ndk以及cmake相关的参数,此处主要有两个点:

  • 通过ndkVersion关键字配置ndk版本,ndk的版本号可以在sdk manager中查询,也可以在sdk的安装路径中,找到ndk文件夹,该目录下按照版本号存放了相关版本的ndk内容。
    C:\Users\xxx\AppData\Local\Android\Sdk\ndk
    在这里插入图片描述
  • 指定的cmake工具,cmake工具的自定义可以在工程的local.properties文件中指定,关键字是cmake.dir,参数为cmake文件夹所在的绝对路径
    sdk.dir=C\:\\Users\\xxx\\AppData\\Local\\Android\\Sdk
    cmake.dir=C\:\\Users\\xxx\\AppData\\Local\\Android\\Sdk\\cmake\\3.17.2
  • 配置cmake版本与解释文件路径,在模块的build.gradle文件中,与defaultConfig同级的目录下添加如下配置
    externalNativeBuild {
        cmake {
            path "../CMakeLists.txt" //编译解释文件路径
            version "3.17.2"  //使用该版本的cmake
        }
    }
  • 配置编译器参数, 在defaultConfig项中的externalNativeBuild项下添加cppFlags关键字可以用来配置编译器参数,如-fno-rtti 关闭运行时类型识别等

  • 配置Cmake参数, 在defaultConfig项中的externalNativeBuild项下添加arguments关键字可以用来配置cmake参数,如-DCMAKE_BUILD_TYPE=Release等

相关配置文件如下所示:

  defaultConfig {
        applicationId ""
        minSdk 21
        targetSdk 30
        versionCode 1
        versionName "1.0"
        //指定NDK版本
        ndkVersion "23.0.7599858"
        externalNativeBuild {
            cmake {
            	//指定编译的CPU架构类型
                abiFilters "arm64-v8a"
                //配置编译器参数
                cppFlags '-DANDROID','-fno-rtti','-s','-Os'
                //配置CMake参数,gradle中配置arugments后,可以直接在
                //cmakelists.txt中使用${CMAKE_BUILD_TYPE}获取该值
                arguments "-DCMAKE_BUILD_TYPE=Release"
            }
        }
   }
    
   externalNativeBuild {
        cmake {
            path "../CMakeLists.txt" //编译解释文件路径
            version "3.17.2"  //使用该版本的cmake
        }
    }

cmake常见语法

  • 添加子工程编译
 命令:add_subdirectory
 语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 
 例子:add_subdirectory(子文件夹cmakelist.txt所在的文件夹路径)

具体场景: 我们在开发app的过程中,可能会存在多个不同功能模块的cpp工程,各个模块分开开发,各自管理编译,因此可以在项目的跟目录新建一个cmakelist.txt文件来包含这些子工程,用于apk的统一编译。 如下:
在这里插入图片描述
其中根目录的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.10.2)
# Declares and names the project.
project("CMakeDemo")
message(WARNING ========= start ============)
add_subdirectory(cpp_project)
add_subdirectory(cpp_project1)
add_subdirectory(app/src/main/cpp/)
message(WARNING ========= end ============)
  • 引入第三方库
引入系统库
命令:find_library
语法:find_library (
          <VAR>
          name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
          [HINTS path1 [path2 ... ENV var]]
          [PATHS path1 [path2 ... ENV var]]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [DOC "cache documentation string"]
          [NO_DEFAULT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )
例子:find_libraray(log-lib log) //从编译链的环境中查找log库, 对应查找的路径
 ${CMAKE_SYSROOT}/${CMAKE_SYSTEM_LIBRARY_PATH}

引入第三方库(不在系统环境中)
第一步:获取第三方库所在路径,如下图所示,根目录工程中的bin文件夹下存在动态与静态两个库,
在根目录的cmakelists.txt中手动配置如下代码

set(DYNAMIC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/dynamic)
set(STATIC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/static)
set(CMAKE_LIBRARY_PATH ${DYNAMIC_PATH} ${STATIC_PATH})
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)

然后我们在子工程中,即可像引用系统库一样的引用第三方的库了

=============================================================
cmake_minimum_required(VERSION 3.10.2)

# Declares and names the project.

project("cpp_project")
message(WARNING >>>>>>>>>>>>>>> cpp_project)
//查找依赖的库
find_library(log-lib log)
find_library(dynamic-lib test_dynamic)
find_library(static-lib test_static)
//链接库
target_link_libraries(cpp_project dynamic-lib static-lib log)

在这里插入图片描述

  • 设置输出路径

修改可执行文件的输出路径

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "输出路径") 

修改库文件的输出路径

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "输出路径") 

CMAKE_RUNTIME_OUTPUT_DIRECTORY,CMAKE_LIBRARY_OUTPUT_DIRECTORY都是cmake工具中自带的属性值,默认情况下,输出路径在工程的app\build\intermediates\cmake\debug\obj${cpu-abi} 中

  • 设置产物文件格式
编译成库文件(动态库,静态库,插件)
add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            source1 [source2 ...])

编译成可执行文件
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               source1 [source2 ...])

JNI操作

单独输出一篇

官方文档

cmake
jni

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值