Android: 使用CMake 构建 JNI 项目

来源:互联网 发布:lol网络波动也被裁决 编辑:程序博客网 时间:2024/06/05 04:42

使用Android Studio 2.2 或更高版本构建JNI项目时默认工具是CMake,最近由于需要编译C文件故尝试了下,确实比 ndk-build方便不少。下面会以android-gpuimage 这个项目为例。

一、下载 NDK 和构建工具
打开SDK管理器:从菜单栏选择 Tools > Android > SDK Manager。或者点击图标 这里写图片描述

这里写图片描述

图来至谷歌开发者中心

下载如图蓝底三项

NDK:这套工具集允许您为 Android 使用 C 和 C++ 代码,并提供众多平台库,让您可以管理原生 Activity 和访问物理设备组件,例如传感器和触摸输入。

CMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。

LLDB:一种调试程序,Android Studio 使用它来调试原生代码。

二、构建项目

构建支持NDK的项目分两种:
1、第一种是 创建支持 C/C++ 的新项目,这种比较简单,创建新项目时选中 Include C++ Support 复选框。 即可,这里不多说了。如图:
这里写图片描述

创建成功后运行即可看见输出一段字符串。

2、第二种是向现有项目添加 C/C++ 代码,这里以将android-gpuimage 里面的library/jni/yuv-decoder.c添加到我们自己的项目中为例。

首先添加源文件:
(1)从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
(2)导航到 您的模块 > src,右键点击 main 目录,然后选择 New > Directory。
(3)为目录输入一个名称(例如 cpp)并点击 OK。
(4)右键点击你刚刚创建的目录,然后选择 New > C/C++ Source File。这里命名:gpuimage-library.c,内容则是上面yuv-decoder.c的内容,请自行拷贝下来。
(5)接着右键点击你刚刚创建的目录,然后选择 New > C/C++ Header File。命名:gpuimage-library.h,内容如下:

#include <jni.h>#ifndef CAMERA_GPUIMAGE_LIBRARY_H#define CAMERA_GPUIMAGE_LIBRARY_H#ifdef __cplusplusextern "C" {#endifJNIEXPORT void JNICALL Java_cn_zz_camerasdk_filter_GPUImageNativeLibrary_YUVtoRBGA(JNIEnv *, jobject, jbyteArray, jint, jint, jintArray);JNIEXPORT void JNICALL Java_cn_zz_camerasdk_filter_GPUImageNativeLibrary_YUVtoARBG(JNIEnv *, jobject, jbyteArray, jint, jint, jintArray);#ifdef __cplusplus}#endif //CAMERA_GPUIMAGE_LIBRARY_H#endif

Tips: 这里需要注意下:方法名跟之前方法一样,Java_包名_类名_方法名 ,请根据自己项目更改!!!

创建完毕后目录如下:


这里写图片描述

接着创建 CMake 构建脚本:
如果你的原生源文件还没有 CMake 构建脚本,则您需要自行创建一个并包含适当的 CMake 命令。CMake 构建脚本是一个纯文本文件,必须将其命名为 CMakeLists.txt。

(1)从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
(2)右键点击 您的模块 的根目录并选择 New > File。
(3)输入“CMakeLists.txt”作为文件名并点击 OK。

编辑CMakeLists.txt内容如下:

# Sets the minimum version of CMake required to build your native library.# This ensures that a certain set of CMake features is available to# your build.cmake_minimum_required(VERSION 3.4.1)# Specifies a library name, specifies whether the library is STATIC or# SHARED, and provides relative paths to the source code. You can# define multiple libraries by adding multiple add.library() commands,# and CMake builds them for you. When you build your app, Gradle# automatically packages shared libraries with your APK.add_library( # Specifies the name of the library.             gpuimage-library             # Sets the library as a shared library.             SHARED             # Provides a relative path to your source file(s).             src/main/cpp/gpuimage-library.c)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.                                  gpuimage-library                                  # Links the target library to the log library                                  # included in the NDK.                                  ${log-lib} )

这里写图片描述

红色部分根据自己项目修改。其中用到的命令可以查看文档:cmake_minimum_required()、add_library()、 find_library()。

然后Gradle 文件配置 CMake

android {    compileSdkVersion 26    buildToolsVersion "26.0.0"    defaultConfig {        minSdkVersion 16        targetSdkVersion 26        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        externalNativeBuild {            cmake {                cppFlags ""            }        }        ndk {          // Specifies the ABI configurations of your native          // libraries Gradle should build and package with your APK.          abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',                   'arm64-v8a'        }    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }    lintOptions {        abortOnError false    }    externalNativeBuild {        cmake {            path "CMakeLists.txt"        }    }}

最后添加Java代码调用部分:
该类也是来自android-gpuimage 项目里面。具体效果可以下载查看。

public class GPUImageNativeLibrary {    static {        System.loadLibrary("gpuimage-library");    }    public GPUImageNativeLibrary() {    }    public static native void YUVtoRBGA(byte[] var0, int var1, int var2, int[] var3);    public static native void YUVtoARBG(byte[] var0, int var1, int var2, int[] var3);}

配置完毕我们编译运行,注意每次修改native方法名时都要clean,然后重新Make Project。

运行成功后选择 Build > Analyze APK。
从 app/build/outputs/apk/ 目录中选择 APK 并点击 OK。
你会在 APK 分析器窗口的 lib// 下看到 libnative-lib.so。

这里写图片描述

好了,今天的分享就到这了,更多信息可以查看:https://developer.android.com/studio/projects/add-native-code.html?hl=zh-cn#new-project

原创粉丝点击