1.Android NDK 介绍
NDK(Native Develop Kit 原生开发工具包)是一组可让在 Android 应用中利用 C 和 C++ 代码的工具。 可以直接将C和C++代码写在项目里,直接构建,也可以使用其他人开发好的C 或者C++库构建自己的项目。
什么情况下需要NDK:
- 计算密集型应用,例如游戏或物理模拟等性能关键项目。
- 重用已经存在的 C 或 C++ 库。
- 有时为了防止算法等机密泄漏
2.创建一个包含C++代码的Android 程序
- 使用 Android Studio 2.3.3 (需要2.2以后版本)
- gradle 插件 2.3.3(需要2.2.0以后版本)
-
已经安装了
NDK - CMake 一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。
-
LLDB 一种调试程序,Android Studio 使用它来调试原生代码。
以上可以从 Tools > Android > SDK Manager 中下载安装(注意科学上网) -
1
-
2
中间各种下一步,直到下面这个页面
环境 1
创建 2
- C++ Standard使用下拉列表选择您希望使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置。
- Exceptions Support如果您希望启用对 C++ 异常处理的支持,请选中此复选框。如果启用此复选框,Android
Studio 会将 -fexceptions 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。 - Runtime Type Information Support如果您希望支持 RTTI,请选中此复选框。如果启用此复选框,Android Studio 会将 -frtti 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。
点击完成按钮,一个牛逼哄哄的程序就出来了,点击运行按钮就会看到运行结果
3 程序剖析
1.文件结构
src/main/cpp/native-lib.cpp 就是我们的C++文件,这里面编写我们要实现的原生方法,然后从我们的MainActivity里通过JNI 来调用。
2.代码剖析
- native-lib.cpp 文件
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_ss007_myfirstndkapp_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */)
{
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
代码很简单,包括了两个头文件,声明并实现了一个方法,这个方法供Java调用。作用就是返回一个字符串”Hello from C++”给调用者。(关于方法的声明规则请参考JNI相关)
- MainActivity 文件
package com.ss007.myfirstndkapp;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity
{
//加载'native-lib' 和'my-lib'两个库
static
{
System.loadLibrary("native-lib");
System.loadLibrary("my-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(String.format("调用native-lib(从源码构建的库) 库中的stringFromJNI函数返回值》%s%n%n调用my-lib(预构建的库)sum函数返回值》%s ",
stringFromJNI(),sum(30,20)));
}
/**
* native-lib 中实现的方法
* @return
*/
public native String stringFromJNI();
/**
* my-lib 中实现的方法
* @param a
* @param b
* @return
*/
public native int sum(int a,int b);
}
这一切是什么发生的呢,关键在CMake。如图所示,你需要将CMark文件配置到模块Gradle中
CMakeList.txt 文件
# 需要获取更多关于CMake的知识请移步到: https://d.android.com/studio/projects/add-native-code.html
#根据你的需要设置要使用CMake的最低版本,版本之间包含的功能有区别
cmake_minimum_required(VERSION 3.4.1)
#创建一个库,三个参数意义:1:库名称;2:库类型,是static的还是shared的;3:要编译为库的源文件
#多次调用这个函数会生成多个库,而且Gradle会自动将Shared类型的库打包到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 )
# 如果C++有头文件,最好还是在这边声明一下路径
include_directories(src/main/cpp/include/)
#********************************NDK API start**********************************
#Android 平台包含了很多预编译的库,CMake会搜索这些库所在的路径,所以你只需提供库名称CMake就可以找到这些库
#find_library 找到目标库(此处为log库)并申明一个变量(log-lib),将这个库的路径存储在这个变量中,以供其他地方使用
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 )
#为了使我们自己生成的原生库native-lib 可以调用NDK 中的log库的函数,需要将原生库链接到log库中
#参数意义:1:要目标库 2:find_library 中找到的库
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library included in the NDK.
${log-lib} )
#我们不仅可以通过上面的方法使用NDK中编译好的库,也可以使用NDK中的源代码文件
#add_library( app-glue
#STATIC
#${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
# You need to link static libraries against your shared native library.
#target_link_libraries( native-lib app-glue ${log-lib} )
#********************************NDK API end**********************************
#********************************使用第三方库 start**********************************
add_library( #给导入的库定义一个变量,以便下面函数调用
imported-lib
SHARED
IMPORTED )
set_target_properties( # Specifies the target library.
imported-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
src/main/jniLibs/${ANDROID_ABI}/my-lib.so )
#********************************使用第三方库 end**********************************
具体如何构建,我已经在CMarkLists.txt 文件做了详细的注释。
note 为了演示 my-lib.so 我只是生成了 armeabi 架构的,如果想了解更多CPU 架构的知识,参考ABI 管理
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/14812.html