在Android Studio中使用Jni

本文介绍了在Android Studio中使用JNI的步骤,包括NDK环境的准备,MainActivity中定义并加载Native方法,创建jni目录及源文件,遵循特定命名规则。详细讲解了Android.mk和Application.mk文件的修改,以及如何通过NDK编译生成.so库。最后提到了修改库目录和gradle.properties以确保动态库生效,并成功运行应用。

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

前提:

NDK环境已经搭建好,

windows下需要安装cygwim

android studio指向正确的ndk




1、新建一个Android项目, 选择Empty Activity



2、在MainActivity中定义Native方法

在static语句块中先加载so库,这时Android Studio会报错,先忽略


package com.cxq.jniexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("JNI",printHello());
    }

    // 新定义的native方法,意思是该方法的具体实现交给c语言实现
    public native String printHello();

    // 加载libprintHello.so动态库,但是我们在加载时必须去掉lib和后缀
    static {
        System.loadLibrary("printHello");
    }
}


3、创建jni文件夹,以及.c/.cpp文件和.h文件

将视图切换至Project下,在app\src\main\目录下创建jni文件夹




在jni文件夹下创建c文件和h文件



编辑.c文件如下:

// 引入头文件
#include <stdio.h>
#include <jni.h>
#include "printHello.h"


// 定义在MainActivity.java类中的printHello对应的C语言函数
jstring Java_com_cxq_jniexample_MainActivity_printHello(JNIEnv* env, jobject obj){
    char* str = "this hello is from jni";
    // 调用 jni.h中定义的创建字符串函数
    jstring string = (*(*env)).NewStringUTF(env, str);
    return string;
}


说明

1、jstring是方法返回值类型,我们可以把jstring看成是java中String跟C语言中char*类型的一个中间转换类型,  

2、方法的命名规则  


Java_[pkgName]_[className]_[funcName]  


pkgName:你的包名,但是不能含".",将其替换为“_”  

className:用到native方法的类名  

funcName:native方法名  

3、方法的形参有两个是必须的也就是不管java中的方法是否有形参,但是C语言中对应的方法必须有JNIEnv* env,和jobject obj,  

    如果java方法中还用其他形参,那么在C语言中严格按照顺序排在jobject obj参数的后面即可。  



至此,Android Studio的部分已经准备完毕。


4、使用NDK编译生成hello.so文件


首先so文件是根据mk文件生成的,因此我们需要先准备好mk文件,方便起见,我们直接从NDK安装目录的sample/hello-jni/jni目录复制文件Android.mkApplication.mk


Android.mk的修改

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := printHello
LOCAL_SRC_FILES := printHello.c

include $(BUILD_SHARED_LIBRARY)

说明:

我们只需要修改LOCAL_MODULE和LOCAL_SRC_FILES两个参数即可。
LOCAL_MODULE参数是指定编译后的目标文件的名称,其实编译好的目标文件名为libhello.so,
LOCAL_SRC_FILES指定了要编译的源文件。


Application.mk的修改


通过修改Application.mk文件来指定生成的动态库的类型:
如按以的修改则只会生成一种动态库:
# Build both ARMv5TE and ARMv7-A machine code.
APP_ABI := armeabi x86

为了方便,也可以指定所有类型

APP_ABI := all

下一步使用cygwin(windows)或则终端进入到工程的jni目录

输入:

${NDK}/ndk-build.cmd

这一步的前提是你已经配置好了NDK的环境



这样so文件会在libs目录下生成



修改jni的库目录 


将app->src->main->libs改成app->src->main->jniLibs

注意:每次运行后ndk-build后,都需要修改这个目录名,否则对动态库的修改不会生效;


修改 gradle->gradle.properties


在文件的最末行添加:

android.useDeprecatedNdk=true


最后运行app,就能出现来自c文件的字符串了。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值