Android NDK初探
什么是NDK?
NDK 是 Native Development Kit 的缩写,是 Android 的工具开发包。它的作用是快速开发 C/C++ 的动态库,并自动将动态库与应用一起打包到 apk。NDK 是属于 Android 的,与 Java 无直接关系。NDK 是 Android 中实现 JNI 的手段。那么什么是JNI呢?
什么是JNI
JNI 是 Java Native Interface 的缩写,即 Java 的本地接口,是java与c语言等其他语言通信的桥梁。目的是使得 Java 与 C/C++进行交互。
开始实战
1.新建native方法
package com.sunql.ndkfrist;
public class JniLoader {
static {
System.loadLibrary("demo-lib");
}
public native String stringFromJNI();
public native String logFormJni();
}
2.创建jni目录,生成jni文件,生成文件代码如下
3.javah
-jni 生成进头文件
-d 输出目录
-classpath <path> 加载引用路径
命令:
(1)进入项目根目录
(2)找到sdk/platforms/android-16/android.jar
(3)javah -classpath bin/classes ;../sdk/platforms/android-16/android.jar -d jni packeageName.className 生成jni文件目录
javah -d jni -classpath F:\Android\Sdk\platforms\android-28\android.jar;....\build\intermediates\classes\debug com.sunql.ndkfrist.J
NITest
4.创建实体类.c 文件 ,引入生成的jni头文件。
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_sunql_ndkfrist_JniLoader_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
5.引入Android.mk文件 ,加入编译的文件配置。
build.gradle配置详情展示:
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.sunql.ndkfrist"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
// 默认是 “ cppFlags "" ”
// 如果要修改 Customize C++ Support 部分,可在这里加入
cppFlags "-frtti -fexceptions"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } }
}
CMakeLists.txt配置文件如下:
cmake_minimum_required(VERSION 3.4.1)
add_library(demo-lib
SHARED
src/main/cpp/demo-lib.cpp )
add_library(test-demo
SHARED
src/main/cpp/test-demo.cpp )
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 )
target_link_libraries(demo-lib
${log-lib} )
target_link_libraries(test-demo
${log-lib} )
6.根目录命令:ndk-build命令生成.so文件。使用android studio开发生成的.so文件会直接在build目录下的intermediates\cmake\debug\obj\arm64-v8a目录中。复制.so文件到其他项目的lib中就可以调用.so中的API方法了。
image.png
7.初始化jni类,调用完成。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JniLoader jniLoader=new JniLoader();
String string= jniLoader.stringFromJNI();
TextView textView=findViewById(R.id.textview);
if (!TextUtils.isEmpty(string)){
textView.setText(string);
}else {
textView.setText("获取null");
}
}
}