Android Studio下 NDK配置与Jni开发流程

本文详细介绍了在Android Studio中配置NDK并进行JNI开发的步骤,包括环境配置、创建本地方法、编写JNI代码、编译生成.so文件以及在Java中加载和调用本地方法。通过实践,作者梳理了整个流程,适合初学者参考。

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

学习学习在学习,闲来无事找个东西学,一直觉得jni可以Java调用C很神奇,于是来探探玄奇,看了网上的关于AS开发环境下 jni的开发文章,对开发的流程还是有点疑问,于是自己动手琢磨了一下,并编写了简单的demo,理清楚了大致流程,本文着重讲述AS下的jni流程,不涉及代码的编写,记录下自己的积累过程,不正确的地方望指出!!!


概念性的就不讲了,来说说流程,说到底也就是那几步


配置ndk

->创建Java文件,编写本地方法

->根据本地方法,在C/C++文件中编写jni代码

->进行编译生成.so链接库文件

->在创建的Java文件中的静态代码块中加载生成.so文件

->在需要调用的地方调用本地方法

一、环境配置

1、在SDK Tools选项下 选择NDK 下载,将下载到对应sdk目录中的ndk-bundle目录

2、将ndk-bundle绝对路径配置到系统的path变量中


cmd命令行输入ndk-build,将会有看着像错误信息的提示,表示配置成功


3、在以下几个文件中配置相关参数
gradler.properties:
android.useDeprecatedNdk=true

local.properties:(指示ndk的路径)
ndk.dir=E\:\\Android\\sdk\\ndk-bundle
sdk.dir=E\:\\Android\\sdk


也可通过Project Structure指定


二、创建本地方法并编译生成.so文件

1、创建Jni.java 文件,在此文件中添加native修饰的方法
package com.haha.jnidemo;

public class Jni {

    public native String getString();

}


2、Terminal 定位到java目录(也可以是其他目录,定位到哪里,执行后面指令生成的.h文件就在那个目录) 
执行 javah com.haha.jnidemo.Jni(包名+类名) 指令 生成.h文件

刷新下目录,如下所示:
3、复制生成的.h文件到jni目录下,创建hello.c文件,并编写逻辑代码

#include "com_haha_jnidemo_Jni.h"
#include "jni.h"

JNIEXPORT jstring JNICALL Java_com_haha_jnidemo_Jni_getString
  (JNIEnv * env, jobject obj){

    return (*env)->NewStringUTF(env, "hello world !");//简单地返回 hello world!字符串
  }
}

此处也可不使用.h文件,之所以用javah命令,是因为会根据我们所定义的本地方法,自动生成相应函数,避免自己手敲带来的意想不到错误,大牛可直接根据本地方法名写出函数(有命名规律)

代码的逻辑编写请自行百度,本文只讲述流程,不涉及如何编写jni代码

4、配置相关参数

app\build.gradle:(主module下的build.gradle)

	android {
		compileSdkVersion 25
		buildToolsVersion "25.0.3"
		defaultConfig {
			...
			
			ndk{
				moduleName "hello"  //待编译生成的目标.so文件名称
				abiFilters "armeabi", "armeabi-v7a", "x86" //编译成这些架构的.so文件
			}
		}


		sourceSets{
			main{
				jniLibs.srcDirs = ['libs']
				jni.srcDirs = []
			}
		}

	}




在app\src\main目录下生成jni目录,(或者 右键app->New->Folder->JNI Folder, 默认是在main目录下生成jni目录)


在jni目录下,创建以下两个文件,名字要一样

Android.mk:
LOCAL_PATH := $(call my-dir)  //包含本文件的当前目录
include $(CLEAR_VARS)

LOCAL_MODULE := hello //生成目标.so文件名称
LOCAL_SRC_FILES := hello.c //待编译成.so文件的.c文件

include $(BUILD_SHARED_LIBRARY)


此文件指示了将哪个.c文件编译成哪个.so文件,需跟app\build.gradle中配置一致


Application.mk:
APP_ABI := armeabi armeabi-v7a x86  //支持什么架构的.so文件  ALL为支持所有,多个架构用空格隔开
APP_PLATFORM := android-14  //min sdk version



5、Terminal 定位到jni目录,执行ndk-build指令对.c文件进行编译,
编译中显示的内容:
执行完ndk-build命令,将会在src\main\java\libs目录下生成几个架构目录,这些目录下有对应的.so文件,前缀为lib

将这些架构目录复制到最外层根目录下libs目录中


至此,.so文件已经编译成功,但是要想链接此文件,需要加载它


6、在Jni.java文件中加入静态代码块,在其中调用System.loadLibrary()方法加载生成的.so文件
package com.haha.jnidemo;

public class Jni {
    static {
        System.loadLibrary("hello");//加载 .so文件
    }

    public native String getString();
}

7、调用Jni中的方法,编译运行app
package com.haha.jnidemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

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

        Jni jni = new Jni();
        String string = jni.getString();
        Toast.makeText(MainActivity.this, "String: " + string,
                Toast.LENGTH_LONG).show();

    }
}

运行起来后,将弹出一个吐司显示hello world!


ps: 如果需要修改native方法的话,在每次修改native方法后,都需要执行ndk-build命令,重新编译生成.so文件,并将其复制到根目录下libs目录中




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值