Android中NDK集成

本文介绍如何在Android应用中使用Java调用C代码。包括创建JNI文件夹、生成头文件、编写C源码及mk文件等步骤,并展示了如何通过Gradle进行配置和编译。

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

Android中Java调用C

在这里插入图片描述

在这里插入图片描述

写文章 NDK使用步骤
下载ndk:

创建 JNI 文件夹
直接在项目右键,选择 New - Folder - JNI Folder ,对话框直接点击 Finish 即可方便地在默认位置创建 jni 文件夹用于存放 c 源码。默认位置在 app/src/main/jni.

在这里插入图片描述

创建 Java 类
首先创建一个 Java 类用于调用 c 代码。
public class JniTest {
static {
System.loadLibrary(“JniLib”);
}
public static native String getString();
}
生成头文件 (.h) 命令行
最直接的方式就是通过命令行生成。
首先使用 javac 编译 java 文件。
小技巧。使用右键按住拖动文件夹到终端面板,可以快速进入对应目录。

在这里插入图片描述

进入到文件所在目录后执行 javac JniTest.java 编译。成功后会出现 JniTest.class 文件。

然后退回到包外目录执行 javah -jni 生成头文件。

在这里插入图片描述

注意路径不要写错了,最后也不需要加文件扩展名。成功后会生成一个 .h 文件,把它手动移到 jni 目录。之前编译出的 .class 文件可以删掉了。最终目录结构如下:

在这里插入图片描述

生成.h文件可以配置工具.

在这里插入图片描述

先起个名字叫,这里叫做 javah.
Program: J D K P a t h JDKPath JDKPath\bin\javah.exe
Arguments: -classpath . -jni -d M o d u l e F i l e D i r ModuleFileDir ModuleFileDir\src\main\jni F i l e C l a s s FileClass FileClass
Working directory: M o d u l e F i l e D i r ModuleFileDir ModuleFileDir\src\main\Java
点击 OK 保存后就新建了一个工具。此时我们右击 JniTest.java,在菜单中选择 External Tools - javah 就可以快速生成头文件并放到 jni 目录。
在这里插入图片描述

编写 c 代码
在 jni 目录新建 一个 c 语言源码,这里叫做 JinLib.cpp. 然后实现头文件中所定义的函数,别忘引入头文件。这里简单地返回一个字符串:
// 头文件 可能不同
#include <cc_chenhe_ndkdemo_JniTest.h>
/*

  • Class: cc_chenhe_ndkdemo_JniTest
  • Method: getString * Signature: ()Ljava/lang/String;
    */
    JNIEXPORT jstring JNICALL Java_cc_chenhe_ndkdemo_JniTest_getString
    (JNIEnv * env, jclass){
    return (*env).NewStringUTF(“Hello cpp”);
    }
    创建 mk 文件
    mk 文件用于告诉 ndk-build 该如何编译 c 源码,详情见官方指南。
    在 jni 目录下创建 Android.mk
    LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := JniLib
LOCAL_SRC_FILES =: JniLib.cpp
include $(BUILD_SHARED_LIBRARY)
其中 LOCAL_SRC_FILES 列出了所有要编译的 c 源码文件。
然后创建 Application.mk
APP_MODULES := JniLib
APP_ABI := all
gradle 配置:
在 module 的 build.gradle 里,android.defaultConfig 下加入下面配置:
ndk{
moduleName “JniLib”
//abiFilters “armeabi-v7a”, “x86” //输出指定abi下的so库
}
sourceSets.main{
jni.srcDirs = []
jniLibs.srcDir “src/main/libs”
}

编译:
首先配置环境,在Path里设置路径,可以直接使用ndk-build。
在cmd里进入jni目录里,使用ndk-build编译.

在这里插入图片描述

运行:添加 Activity 的代码:
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TextView tv = findViewById(R.id.text_view);
    tv.setText(JniTest.getString());
}

}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

package com.example.ndkday15;

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;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    private TextView tv;
    private String s;
    private String s2;
    private EditText editText;
    private EditText editText2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method

        initview();


    }

    private void initview() {

        tv = findViewById(R.id.sample_text);
        findViewById(R.id.btn_jia).setOnClickListener(this);
        findViewById(R.id.btn_jian).setOnClickListener(this);
        findViewById(R.id.btn_cheng).setOnClickListener(this);
        findViewById(R.id.btn_chu).setOnClickListener(this);

        editText = findViewById(R.id.ed);
        editText2 = findViewById(R.id.ed2);
    }

    /**
     * ,
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */



    public native int addAb(int a, int b);

    public native int jianAb(int a, int b);

    public native int chengAb(int a, int b);

    public native int chuAb(int a, int b);

    @Override
    public void onClick(View v) {
        s = editText.getText().toString();
        s2 = editText2.getText().toString();
        switch (v.getId()) {
            case R.id.btn_jia:
                tv.setText(addAb(Integer.valueOf(s), Integer.valueOf(s2)) + "");
                break;

            case R.id.btn_jian:
                tv.setText(jianAb(Integer.valueOf(s), Integer.valueOf(s2)) + "");
                break;
            case R.id.btn_cheng:
                tv.setText(chengAb(Integer.valueOf(s), Integer.valueOf(s2)) + "");
                break;
            case R.id.btn_chu:
                if (s2.equals("0") || s.equals("0")) {
                    Toast.makeText(this, "除数或者被除数不能为0", Toast.LENGTH_SHORT).show();
                } else {
                    tv.setText(chuAb(Integer.valueOf(s), Integer.valueOf(s2)) + "");

                }
                break;
        }
    }
}

#include <jni.h>
#include <string>


extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkday15_MainActivity_addAb(JNIEnv *env, jobject instance, jint a, jint b) {

    // TODO: implent addAb()

    return a+b;

}extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkday15_MainActivity_jianAb(JNIEnv *env, jobject instance, jint a, jint b) {

    // TODO implent jianAb()
    return a-b;
}extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkday15_MainActivity_chengAb(JNIEnv *env, jobject instance, jint a, jint b) {

    // TODO implent chengAb()

    return  a*b;
}extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkday15_MainActivity_chuAb(JNIEnv *env, jobject instance, jint a, jint b) {

    // TODO implent chuAb()


    return a/b;
}

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值