NDK和JNI

本文介绍了Android NDK的基本概念、配置步骤、特点,以及JNI的定义和用途。通过一个简易计算器的代码示例,展示了如何在Android中使用NDK和JNI实现Java与C/C++的交互,实现高效计算或利用本地库的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、NDK介绍

NDK介绍:
定义:Native Development Kit,是 Android的一个工具开发包
NDK是属于 Android 的,与Java并无直接关系
作用:快速开发C、 C++的动态库,并自动将so和应用一起打包成 APK。
可通过 NDK在 Android中使用 JNI与本地代码(如C、C++)交互

二、NDK步骤

  1. 配置 Android NDK环境
    A, Android 原生开发工具包:就是ndk工具包。
    B, LLDB:一种调试程序,Android Studio 使用它来调试原生代码。
    C, 下载这些组件:
    D, 在打开的Android Studio项目中,从菜单栏选择 Tools > Android > SDK Manager。
    E, 点击 SDK Tools 标签。
    F, 选中 LLDB、CMake 和 NDK 旁的复选框

  2. 创建 Android 项目,并与 NDK进行关联(创建工程时,Include C C++)。
    在这里插入图片描述

  3. 创建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;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值