一. 前言 1. NDK && JNI ?
JDK:Java Development Kit
SDK:Software Development Kit
NDK:Native Development Kit
JNI:Java Native Interface
NDK 是 Android平台用来支持 C/C++ 开发的。
2. 使用 NDK 的优劣 ① 优点:
代码的保护。apk的java层代码很容易被反编译,而 C/C++库 反汇难度较大。
可以方便地使用现存的开源库。很多现存的开源优秀库都是用 C/C++ 代码编写的。
提高程序的执行效率。将要求高性能的应用逻辑使用 C开发,从而提高应用程序的执行效率。
便于移植。用 C/C++ 写的库可以方便在其他嵌入式平台上再次使用。
② 缺点:
③ 注意:
要不要使用?什么情况下使用它?
使用 NDK 大部分情况是需要将一些已有的 C函数 移植到 Android平台 所选择的快捷方法,而不是作为提高代码效率的手段。
3. 学什么?
一种是已经编译好的 .so
动态库。
一种是使用 C/C++ 源代码开发。
二. 代码实战 首先放出:官方文档 。
1. 准备工作-下载 NDK 和工具 要为您的应用编译和调试原生代码,您需要以下组件:
Android 原生开发套件 (NDK):这套工具使您能在 Android 应用中使用 C 和 C++ 代码。
CMake:一款外部编译工具,可与 Gradle 搭配使用来编译原生库。如果您只计划使用 ndk-build,则不需要此组件。
LLDB:Android Studio 用于调试原生代码的调试程序。(我找不到哪里可以下载,我猜是默认集成了)
2. 创建一个 Native C++ 项目
C++ Standard
:指定编译库的环境,其中Toolchain Default
使用的是默认的CMake
环境;C++ 11
也就是C++环境。两种环境都可以编库。
我第一次出现以下的错误,我的理解是没有下载对应的版本,点击下载等待完成后同步一下即可。
3. 默认产生的文件 native-lib.cpp:原生的静态库,在使用的时候需要提前加载。
CMakeLists.txt:所有需要用到的cpp文件都需要放在其中,以便加入到项目中。
4. 自己创建 C++ 文件 ① 创建C++文件,其中的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 #ifndef INC_06_05_NDKTEST_TEST_H #define INC_06_05_NDKTEST_TEST_H #include <string> using namespace std ;class Test { public : string getTestString (string str) ; }; #endif
1 2 3 4 5 #include "Test.h" string Test::getTestString (string str) { return "NDK开发测试函数:" +str; }
② 创建C++文件之后,还需要添加到CMakeLists.txt文件中,native-lib.cpp已经默认被加入其中了。
5. 使用自己创建的C++类里面的方法 ① Activity中的调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class MainActivity extends AppCompatActivity { static { System.loadLibrary("native-lib" ); } @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.sample_text); tv.setText(getTestString("参数" )); } public native String stringFromJNI () ; public native String getTestString (String str) ; }
② native-lib.cpp文件中的调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <jni.h> #include <string> #include "Test.h" extern "C" JNIEXPORT jstring JNICALLJava_swu_xl_baidu_ndktest_MainActivity_stringFromJNI( JNIEnv* env, jobject ) { std ::string hello = "Hello from C++" ; return env->NewStringUTF(hello.c_str()); } extern "C" JNIEXPORT jstring JNICALL Java_swu_xl_baidu_ndktest_MainActivity_getTestString(JNIEnv *env, jobject thiz, jstring str) { const char *xl_str = (env->GetStringUTFChars(str, 0 )); Test* test = new Test; std ::string result = test->getTestString(xl_str); return env->NewStringUTF(result.c_str()); }
③ 运行效果
三. 源代码 NDKTest
参考文章 Android NDK开发(一)
NDK开发学习(一) —创建一个支持c/c++的项目
android jni 中jstring字符串的转化 和 一些常用数据转化
官方文档-NDK 入门指南