一、NDK介绍
NDK介绍:
定义:Native Development Kit,是 Android的一个工具开发包
NDK是属于 Android 的,与Java并无直接关系
作用:快速开发C、 C++的动态库,并自动将so和应用一起打包成 APK。
可通过 NDK在 Android中使用 JNI与本地代码(如C、C++)交互
二、NDK步骤
-
配置 Android NDK环境
A, Android 原生开发工具包:就是ndk工具包。
B, LLDB:一种调试程序,Android Studio 使用它来调试原生代码。
C, 下载这些组件:
D, 在打开的Android Studio项目中,从菜单栏选择 Tools > Android > SDK Manager。
E, 点击 SDK Tools 标签。
F, 选中 LLDB、CMake 和 NDK 旁的复选框 -
创建 Android 项目,并与 NDK进行关联(创建工程时,Include C C++)。
-
创建Ndk工程项目和之前的区别:
① 会发现多了一个 CMakeLists.txt 文件和 .externalNativeBuild 文件夹。
• CMakeLists.txt 相当于 CMake 的配置文件
• .externalNativeBuild 是自动生成的构建脚本
② main 文件夹下多了一个 cpp 文件夹,里面用来放置 C/C++ 代码。
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.bawei.jni.demojni"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner android {
compileSdkVersion 28
defaultConfig {
applicationId "com.bawei.jni.demojni"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
//配置参数
cppFlags ""
//设置生成指定 ABI 版本的 so 库
abiFilters 'armeabi-v7a', 'armeabi'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
4.使用 Android需要交互的本地代码 实现在Android类中声明的Native方法。
比如 Android 需要与 C++ 交互,那么就用C++ 实现 Java的Native方法
5.通过 cMake 命令编译产生.so库文件。
三、NDK特点
四、JNI介绍
- 定义:Java Native Interface,即 Java本地接口
- 作用: 使得Java 与 本地其他类型语言(如C、C++)交互 .
- 在下面几种情况下,我们要使用JNI:
1、 程序当中用到了 JAVA API 不提供的特殊系统环境才会有的特征。而跨进程操作又不现 实。
2、 你可能想访问一些己有的本地库,但又不想付出跨进程调用时的代价,如效率,内存, 数据传递方面。
3、JAVA 程序当中的一部分代码对效率要求非常高,如算法计算,图形渲染等。 - 在 Java代码 里调用 C、C++等语言的代码 或 C、C++代码调用 Java 代码
- 特别注意:
JNI是 Java 调用 Native 语言的一种特性。
JNI 是属于Java 的,与 Android无直接关系。
JNI 的强大特性使我们在使用 Java 平台的同时,还可以重用原来的本地代码。作为虚拟机 实现的一部分,JNI 允许 Java 和本地代码间的双向交互。
五、代码示例 —简易计算器
//Activity类
package bw.com.myapplicationc;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
TextView showResult;
EditText input_a;
EditText input_b;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
Button add_B = findViewById(R.id.add_B);
Button minus_B = findViewById(R.id.minus_B);
Button mul_B = findViewById(R.id.mul_B);
Button divide_B = findViewById(R.id.divide_B);
showResult = findViewById(R.id.showResult);
input_a = findViewById(R.id.input_a);
input_b = findViewById(R.id.input_b);
add_B.setOnClickListener(this);
minus_B.setOnClickListener(this);
mul_B.setOnClickListener(this);
divide_B.setOnClickListener(this);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native int add(int a,int b);
public native int minus(int a,int b);
public native int mul(int a,int b);
public native int divide(int a,int b);
@Override
public void onClick(View v) {
int a = Integer.parseInt(input_a.getText().toString());
int b = Integer.parseInt(input_b.getText().toString());
switch (v.getId()){
case R.id.add_B:
showResult.setText(add(a,b)+"");
break;
case R.id.minus_B:
showResult.setText(minus(a,b)+"");
break;
case R.id.mul_B:
showResult.setText(mul(a,b)+"");
break;
case R.id.divide_B:
showResult.setText(divide(a,b)+"");
break;
}
}
}
//C++类
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_bw_com_myapplicationc_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT jint JNICALL
Java_bw_com_myapplicationc_MainActivity_add(JNIEnv *env, jobject instance, jint a, jint b) {
// TODO
return a+b;
}extern "C"
JNIEXPORT jint JNICALL
Java_bw_com_myapplicationc_MainActivity_minus(JNIEnv *env, jobject instance, jint a, jint b) {
// TODO
return a-b;
}extern "C"
JNIEXPORT jint JNICALL
Java_bw_com_myapplicationc_MainActivity_mul(JNIEnv *env, jobject instance, jint a, jint b) {
// TODO
return a*b;
}extern "C"
JNIEXPORT jint JNICALL
Java_bw_com_myapplicationc_MainActivity_divide(JNIEnv *env, jobject instance, jint a, jint b) {
// TODO
return a/b;
}