先说下题外话哈,最近做了个领取电商平台优惠券的小程序,扫码支持下哈~
现在越来越多的app需要进行ndk开发,尤其音视频这块,本人最近准备学习android音视频开发,发现ndk这块绕不过去,所以就记录下学习的点滴,方便以后查阅。
工具准备
在 android studio 上进行 ndk 开发,相关的工具肯定少不了了,准备很方便,打开 SDK Tools ,勾选LLDB、CMake、NDK 进行安装即可。
新建ndk开发项目
在新建项目时,勾选 C++ 支持
一路 next ,最后一步,设置 C++ 标准,这个东西我不太懂,反正使用默认的 Toolchain Default 时,工程使用的是 Cmake 对 native code 进行编译,网上好多ndk开发环境搭建的教程是根据 Android.mk、Application.mk写的,在Cmake下跑不起来(一把泪~~)
新建的 ndk 开发项目结构上与普通项目的区别主要有以下几点:
- 新增CMakeLists.txt:CMake、ndk-build 的构建脚本
- 新增 cpp 目录:native 源文件、头文件等
- build.gradle(app)文件增加了对 externalNativeBuild 的配置
重点看下 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).
src/main/cpp/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在Android Studio的更多信息,请阅读文档:https://d.android.com/studio/projects/add-native-code.html
# 设置CMake的最低版本构建本机所需库
cmake_minimum_required(VERSION 3.4.1)
# 创建并命名库,将其设置为静态的
# 或共享,并提供其源代码的相对路径。
# 你可以定义多个library库,并使用CMake来构建。
# Gradle会自动将包共享库关联到你的apk程序。
add_library( # 设置库的名称
native-lib
# 将库设置为共享库。
SHARED
# 为源文件提供一个相对路径。
src/main/cpp/native-lib.cpp )
# 搜索指定预先构建的库和存储路径变量。因为CMake包括系统库搜索路径中默认情况下,只需要指定想添加公共NDK库的名称,在CMake验证库之前存在完成构建
find_library( # 设置path变量的名称
log-lib
# 在CMake定位前指定的NDK库名称
log )
# 指定库CMake应该链接到目标库中,可以链接多个库,比如定义库,构建脚本,预先构建的第三方库或者系统库
target_link_libraries( # 指定目标库
native-lib
# 目标库到日志库的链接 包含在NDK
${log-lib} )
下载构建下项目,就是点击 adroid studio 菜单 Build—>Rebuild Project,就会自动把 native 源文件编译为各个平台用的 .so 文件。
安装到设备后工程就可以正常运行了,具体的 java/native 代码调用方式后面再说。
在已有普通项目上进行ndk开发
- 首先在 main 目录下新建 cpp 文件夹,存放 native 源文件。
- 在 MainActivity 中添加 native 代码,myNativeMethod() 方法现在是红色的,因为现在还没有对应的native层方法实现,下面继续。
- 命令行进入 src/main/java 目录下,执行 javah 命令,生成 native 头文件,就是 .h 文件,然后移动该 .h 文件到刚才新建的 cpp 目录下。
- 现在有了 native .h 头文件,头文件中只有对方法的声明,没有方法的实现,还需要对头文件进行实现。在 cpp 目录下新建 MyNative.cpp 文件,输入代码。
#include "com_wyt_one_MainActivity.h"
#include
#include
extern "C" JNIEXPORT jstring
JNICALL
Java_com_wyt_one_MainActivity_myNativeMethod(
JNIEnv *env,
jobject /* this */) {
return env->NewStringUTF("myNativeMethod 执行了");
}
- 经过上面几步,ndk开发需要的源文件和 activity 里的调用代码已经完成了,调用代码现在还是红色的,因为现在还没有对 native 源文件进行编译,编译需要 CMakeLists.txt 文件,上文提到过,所以在 app 目录下新建 CMakeLists.txt 文件,把上文给出的 CMakeLists.txt 代码粘贴进去,稍加修改(把 native-lib 都改为 MyNative)
# 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.
MyNative
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/MyNative.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.
MyNative
# Links the target library to the log library
# included in the NDK.
${log-lib} )
- 编辑 build.gradle(app) 文件,配置 CMake。
- rebuild 工程,即可生成 .so 文件,activity 里的 native 方法调用也不红了
- 在界面上添加一个 Button ,点击时调用 native 方法,将按钮显示的文本更新为 native 方法返回的字符串。
总结
本文介绍了 ndk 开发所需要的工具,对新创建项目和已有项目两种 ndk 开发场景下的环境搭建的流程进行了描述。