JNI入门指南

7 篇文章 0 订阅
1 篇文章 0 订阅

一、配置JNI开发环境
1.在Android studio 的SDK Tools里面下载NDK 和CMake,并配置ndk的环境变量。
在这里插入图片描述
2.在local.properties添加配置ndk路径

sdk.dir=D\:\\software_install\\Android\\sdk
ndk.dir=D\:\\software_install\\Android\\sdk\\ndk //这里要添加自己的ndk路径,记得不要直接复制粘贴就完事。

3.在gradle.properties中添加

android.useDeprecatedNdk=true   //表示兼容老的ndk版本

二、编写Java代码
1.新建TestJni类

package com.zzq.testjni.jni;

public class TestJni {
    public native void add(int a,int b);
    public native String getString();
}

2.生成.h头文件
(1)利用javac命令生成TestJni.class文件

javac TestJni.java //在TestJni.java文件所在目录执行此命令

(2)利用javah命令生成.h头文件

javah -classpath . -jni com.zzq.testjni.jni.TestJni  

注意:这个命令必须在TestJni类包名的前一级目录下执行,如TestJni.java的完整路径名是
D:\workspace\0920\AndroidPerformanceMonitor-master\TestJNI\app\src\main\java\com\zzq\testjni\jni\TestJni.java
后面的com\zzq\testjni\jni是TestJni的包名,则此命令就需要在java目录下执行。
执行成功后会生成如下com_zzq_testjni_TestJni.h头文件。
在这里插入图片描述
头文件类容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_zzq_testjni_jni_TestJni */

#ifndef _Included_com_zzq_testjni_jni_TestJni
#define _Included_com_zzq_testjni_jni_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_zzq_testjni_jni_TestJni
 * Method:    add
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_com_zzq_testjni_jni_TestJni_add
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     com_zzq_testjni_jni_TestJni
 * Method:    getString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_zzq_testjni_jni_TestJni_getString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

这里面有对应我们在TestJni.java中写的两个方法的函数。

JNIEXPORT void JNICALL Java_com_zzq_testjni_jni_TestJni_add
  (JNIEnv *, jobject, jint, jint);

JNIEXPORT jstring JNICALL Java_com_zzq_testjni_jni_TestJni_getString
  (JNIEnv *, jobject);

这里的JNIEnv 可以理解为java中的上下文,jobject就是调用这个函数的对象。
三、生成so库
1.利用Clion创建一个C++ library的项目
2.将上面生成的com_zzq_testjni_TestJni.h文件拷贝到这个项目
这时,应该会报找不到jni.h文件的错误,这时需要到jdk的安装目录\jdk\include下面找到该文件,复制过来,并将#include <>的尖括号改为“”即可。

扩展:
#include  <>  表示引入的系统头文件
#include  ""   表示引入的自己的头文件

这时应该还有JNIEXPORT关键字报红,我们再把\jdk\include\win32下面的jni_md.h文件拷贝到项目里面去

3.新建同名的.c文件(com_zzq_testjni_TestJni.c),来实现.h文件里面定义的函数。

  • 在加入com_zzq_testjni_TestJni.c里面加入以下代码,与com_zzq_testjni_TestJni.h文件建立关联。

     #include "com_zzq_testjni_jni_TestJni.h"
    
  • 在加入com_zzq_testjni_TestJni.c里面加入以下代码,实现com_zzq_testjni_jni_TestJni_getString函数

    JNIEXPORT jstring JNICALL Java_com_zzq_testjni_jni_TestJni_getString
        (JNIEnv * env, jobject jobject1){
    return (*env)->NewStringUTF(env,"我是C定义的String");
    }
    

4.配置CMakeLists.txt文件

add_library(mathlib SHARED com_zzq_testjni_jni_TestJni.h com_zzq_testjni_jni_TestJni.c)
  • mathlib 为自定义库的名称
  • SHARED 表示这个是共享库
  • com_zzq_testjni_jni_TestJni.h 、com_zzq_testjni_jni_TestJni.c 这是这个库的代码。

5.然后直接build project 就会生成如下文件
在这里插入图片描述
这里的.dll文件就是动态链接库。但只能在windows 环境下用,如果想在Android环境下使用,还需要用.so库。

简单介绍下so库的简单编译流程,后面会单独出详细教程。
(1) 在linux环境 的ubuntu系统里面 安装ndk,配置ndk环境
(2) 把第三方库的源码拉下来
(3) 官网看下有没有提供编译脚本build.sh或者是readme.txt或者是configure.
(4) 编译.so库

四、知识问答
1.JNIEnv是什么?
JNIEnv是一个线程相关的结构体,该结构体代表了Java在本线程的执行环境,通过JNIEnv的实例对象可以调用Java代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值