下面是详解Android Studio NDK配置CMake开发Native C的完整攻略。
一、前置条件
在进行此项操作前,先确保以下环境已准备好:
- Android Studio
- NDK(可以在 Android Studio 中下载)
- CMake
二、配置 CMake
CMake 是一个开源程序,它可以管理代码的编译过程。在 Android Studio 中使用 CMake 可以轻松配置 C/C++ 代码的编译过程。我们需要先配置 CMake,从而实现使用 CMake 开发 Native 代码。
(一)在 Android Studio 中配置 CMake
- 打开 Android Studio。
- 打开您的 Android 项目。
- 如果还没有,可以添加一个 cpp 文件。右键点击您的项目的 app/src/main 目录 ,选择 New > C++/JNI > C++ File。
- 在C++文件中输入一些代码,以便 Cmake 和 NDK 可以查看配置情况。例如:
```c++
#include
#include
#include
#define LOG_TAG "HelloWorld"
#define LOGI(...) android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS)
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_hellojni_MainActivity_stringFromJNI(JNIEnv env,
jobject / this */) {
std::string hello = "Hello from C++";
LOGI("I am the hello-jni-javatest!");
return env->NewStringUTF(hello.c_str());
}
```
这是一个简单的 hello world 的 C++ 文件,它可以把字符串传递给调用该函数的 Java 代码。
- 打开 CMakeLists.txt 文件,它在您的项目的 /app/CMakeLists.txt 目录下。该文件控制 CMake 的配置过程。在文件中输入以下代码:
```
cmake_minimum_required(VERSION 3.4.1)
# set up shared library
add_library(hello-jni SHARED
hello-jni.cpp)
find_library(log-lib log)
# linking shared library to log library
target_link_libraries(hello-jni ${log-lib})
```
此代码片段告诉 CMake 创建一个名为“hello-jni”的共享库,并将其与 hello-jni.cpp 源代码链接。此文件还告诉 CMake 链接该库与 Android 的 log 库。
(二)在 Android Studio 中生成应用程序
- 选择 Build > Make Project,Android Studio 将使用 CMake 编译您的项目。
- 使用 Build > Rebuild Project 将重新生成项目,以确保更改已应用。
三、配置 和 实现 NDK
在了解了如何配置 CMake 之后,我们现在可以继续设置 NDK 来生成本机代码。此操作需要打开项目中的 build.gradle 文件。
- 在应用程序级别的 build.gradle 文件中添加以下块。此块指定您要使用的 CMake 版本并告诉 Android Studio 您是否要构建本机代码:
externalNativeBuild {
cmake {
version "3.10.2"
path "CMakeLists.txt"
}
}
- 接下来,添加以下两个 NDK 环境变量以应用程序级别的 build.gradle 文件中:
```
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags "-fexceptions"
}
}
}
//配合之前添加的CMake块以使用CMake构建并传递信息
externalNativeBuild {
cmake {
version "3.10.2"
path "CMakeLists.txt"
}
}
//添加NDK路径,注意替换为自己的NDK路径
ndk {
platformVersion 27
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86','x86_64'
defualtConfig.ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86','x86_64'
}
//注意替换为自己的NDK路径
path "C:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\ndk-bundle"
}
}
```
- 现在,使用以下语句将您的 hello-jni 应用程序从 Java 调用你设置的本机语言 C++ 文件:
String outputString = null;
// /data/data/[package]/lib
File libraryFile = context.getDir("lib", Context.MODE_PRIVATE);
System.loadLibrary("hello-jni");
HelloJni helloJni = new HelloJni();
outputString = helloJni.stringFromJNI();
到这里,配置 CMake 和 NDK 的过程就已经完成了。接下来,让我们通过两个示例来更好地理解。
四、示例说明
示例1:整数加法运算
1.添加 native 方法:
需在你的 MainActivity.java 文件中,添加通过 native 关键字定义的 add 方法,该方法接受两个整数参数并返回它们的和。
package com.example.ndkespresso;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
static {
System.loadLibrary("native-lib");
}
private native int add(int a, int b);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int x = 4;
int y = 6;
int sum = add(x, y);
Log.d(TAG, "Sum of " + x + " and " + y + " is: " + sum);
}
}
2.添加本机代码 CPP:
接下来,我们需要实现 add 方法的本机代码。在您的 Android 项目中,在您的 cpp 文件中添加以下代码片段:
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkespresso_MainActivity_add(JNIEnv *env, jobject object, jint a, jint b) {
return a+b;
}
现在,编译和运行应用,你将在控制台中看到你添加的日志打印出合计值。
示例2:基本算法-冒泡排序算法
1.添加 native 方法:
需在你的 MainActivity.java 中添加通过 native 关键字定义的 sort 方法。该方法将接受一个 int 数组和 int 数组的长度作为参数,并按升序对数组进行排序。
package com.example.ndkespresso;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
static {
System.loadLibrary("native-lib");
}
private native int[] sort(int[] unsorted, int length);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int arr[] = {1, 60, 90, 77, 99, 1, 200, 400};
Log.d(TAG, "Initial Array : " + Arrays.toString(arr));
int sortedArr[] = sort(arr, arr.length);
Log.d(TAG, "Sorted Array : " + Arrays.toString(sortedArr));
}
}
2.添加本机代码 CPP:
接下来,添加本机代码以对传递的整数数组进行排序。您可以使用 c++ 冒泡排序来实现此目的。
在您的 Android 项目中,在您的 cpp 文件中添加以下代码片段:
#include <jni.h>
#include <string>
#include <algorithm>
#include <vector>
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_example_ndkespresso_MainActivity_sort(JNIEnv *env, jobject thiz, jintArray unsorted,
jint length) {
std::vector<int> vec;
jint *array = env->GetIntArrayElements(unsorted, nullptr);
if (array) {
for (int i = 0; i < length; i++) {
vec.push_back(array[i]);
}
}
env->ReleaseIntArrayElements(unsorted, array, JNI_ABORT);
// sorted vector using standard library
std::sort(vec.begin(), vec.end());
jintArray result = env->NewIntArray(length);
if (result == nullptr) {
return nullptr; /* out of memory error thrown */
}
jint *nativeArray = env->GetIntArrayElements(result, nullptr);
if (nativeArray == nullptr) {
return nullptr; /* out of memory error thrown */
}
// copy vector to native array
for (int i = 0, n = vec.size(); i < n; i++) {
nativeArray[i] = vec[i];
}
env->ReleaseIntArrayElements(result, nativeArray, 0); // release 'resultArray'
return result; // return the jni array
}
现在,编译和运行应用程序,您将在控制台中看到您打印的排序数组。
到这里,我们就成功地完成了 Android Studio NDK配置CMake开发native C的完整攻略,希望能对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Android studio ndk配置cmake开发native C - Python技术站