问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Android JNI入门:概念、应用场景及实战Demo

创作时间:
作者:
@小白创作中心

Android JNI入门:概念、应用场景及实战Demo

引用
CSDN
1.
https://blog.csdn.net/wenzhi20102321/article/details/136291126

JNI(Java Native Interface)是Android开发中的一个重要技术,它允许Java代码调用C/C++代码,从而实现更高效、更底层的功能。本文将详细介绍JNI的基本概念、应用场景,并通过一个简单的Demo展示如何在Android项目中使用JNI。

JNI的简单介绍

JNI

JNI全称Java Native Interface,即Java本地方法接口。它提供了一种Java字节码调用C/C++的解决方案。这里的"本地"指的是C/C++,因此JNI可以理解为Java调用C/C++的方案技术。

NDK

NDK(Native Development Kit)是Android的本地开发工具集。它允许开发者将C或C++代码编译成Android可识别的格式。NDK描述的是工具集,其主要功能是将C/C++代码编译成Java可以识别的模块。

Jni的开发背景

JNI的主要应用场景包括:

  • 需要调用Java语言不支持的依赖于操作系统平台特性的一些功能
  • 在程序对时间敏感或对性能要求特别高的情况下,使用更底层的语言来提高运行效率
  • 音视频开发涉及到的音视频编解码需要更快的处理速度
  • 整合一些以前的非Java语言开发的系统
  • 使用早期实现的C/C++语言开发的一些功能或系统

JNI在Android开发里的主要应用场景

JNI在Android开发中主要应用于以下场景:

  • 音视频开发
  • 热修复
  • 插件化
  • 逆向开发

JNI的简单Demo

1. Demo主要界面和效果展示

在Android Studio中新建一个JNI项目,完成后即可创建一个最简单的JNI项目。可以直接点击运行在模拟器上或者连接的Android设备,即调用了CPP文件返回字符串并在Android界面显示Hello World,项目代码就包含了一个最基本的jni架构代码。

本文Jni 示例Demo实现加减乘除运算,以及字符串拼接,如下图所示:

2. CMake编译加载文件

CMakeLists.txt 大致内容如下:

cmake_minimum_required(VERSION 3.18.1) //版本
project("jnidemo") //加载的项目
//至少三个参数,参数直接没有标点符号哦,用换行隔开
第一个参数表示加载的库文件(动态.so/静态.a)
第二个参数表示库加载的方式,有动态SHARED,有静态STATIC(极少用)
后面的参数可以N个,表示要加载的CPP文件,也可以用集合指向
add_library(
        jnidemo
        SHARED
        native-lib.cpp
        TestCPlus.cpp
)
//下面两个是关联的,简单示例中不写也是可以正常运行的
find_library(
        log-libxx
        log)
target_link_libraries(
        jnidemo
        ${log-libxx})

3. MainActivity.java

public class MainActivity extends AppCompatActivity {
    //加载so库名称的代码
    // Used to load the 'jnidemo' library on application startup.
    static {
        System.loadLibrary("jnidemo");
    }
    //界面显示代码省略
    //jni方法,加减乘除,最后一个参数是操作类型的字节数据类型
    public native float operationNumberFromJNI(float parameter1, float parameter2, char type);
    //jni方法,字符串拼接
    public native String addStringFromCPlusJNI(String parameter1, String parameter2);
}

4. native-lib.cpp

#include <jni.h>
#include <string>
//创建Jni工程最简单的方法,返回一个字符串
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_jnidemo_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "简易计算器";
    return env->NewStringUTF(hello.c_str());
}
//Jni增删改查的实现,因为float是基本数据类型,所以不需要转换就可以直接操作
extern "C"
JNIEXPORT jfloat JNICALL
Java_com_example_jnidemo_MainActivity_operationNumberFromJNI(JNIEnv *env, jobject thiz, jfloat parameter1,
                                                                  jfloat parameter2,jchar type) {
    switch (type) {
        case '+':
            return parameter1 + parameter2;
        case '-':
            return parameter1 - parameter2;
        case '*':
            return parameter1 * parameter2;
        case '/':
            return parameter1 / parameter2;
    }
    return parameter1 + parameter2;
}
//字符串的拼接,方法有N种,String不是基本数据类型,需要进行类型转换后才能进行操作
extern "C" JNIEXPORT _jstring * JNICALL
Java_com_example_jnidemo_MainActivity_addStringFromCPlusJNI(JNIEnv *env, jobject thiz,
                                                            jstring parameter1,
                                                            jstring parameter2) {
    char *c1 = (char *) (env->GetStringUTFChars(parameter1, JNI_FALSE));
    char *c2 = (char *) (env->GetStringUTFChars(parameter2, JNI_FALSE));
    char *res = strcat(c1, c2); //拼接两个字符串
    //释放c1和c2
    delete(c1);
    delete(c2);
    return env->NewStringUTF(res);
}

其他

1. Jni基础的几点内容

  • 记住编写关键流程
  • 类的静态方法中loadLibrary
  • 类中定义native方法
  • 类的使用中调用jni方法
  • cpp文件中编写jni实现
  • CMakeList.txt 的基本规则
  • jni.cpp文件中的方法命名
  • Java到jni.cpp文件中类型转换
  • 有一定的c/c++语言基础

2. java数据类型与jni类型映射表

Java 类型
JNI本地类型
描述
boolean
jboolean
C/C++8位整型
byte
jbyte
C/C++带符号的8位整型
char
jchar
C/C++无符号的16位整型
short
jshort
C/C++带符号的16位整型
int
jint
C/C++带符号的32位整型
long
jlong
C/C++带符号的64位整型e
float
jfloat
C/C++32位浮点型
double
jdouble
C/C++64位浮点型
Object
jobject
任何Java对象,或者没有对应java类型的对象
Class
jclass
Class对象
String
jstring
字符串对象
Object[]
jobjectArray
任何对象的数组
boolean[]
jbooleanArray
布尔型数组
byte[]
jbyteArray
比特型数组
char[]
jcharArray
字符型数组
short[]
jshortArray
短整型数组
int[]
jintArray
整型数组
long[]
jlongArray
长整型数组
float[]
jfloatArray
浮点型数组
double[]
jdoubleArray
双浮点型数组

3. Java签名类型 常用的数据类型及对应字符

Java 类型
Jni中表示的符号
备注
boolean
Z
不是类型首字母大写
byte
B
char
C
short
S
int
I
long
L
float
F
double
D
void
V
objects对象
Lfully-qualified-class-name;L全类名;
记得最后是有分号的
Arrays数组
[array-type [数组类型
methods方法
(argument-types)return-type(参数类型)返回类型

4. JNI类型api调用表格

方法、变量修饰类型表格

函数描述
描述
GetFieldID
得到一个实例的域的ID
GetStaticFieldID
得到一个静态的域的ID
GetMethodID
得到一个实例的方法的ID
GetStaticMethodID
得到一个静态方法的ID

数组对应变量类型api表格

函数描述
nativie数据对象
nativie类型
Java数据类型
GetBooleanArrayElements
jbooleanArray
jboolean
boolean[]
GetByteArrayElements
jbyteArray
jbyte
byte[]
GetCharArrayElements
jcharArray
jchar
char[]
GetShortArrayElements
jshortArray
jshort
short[]
GetIntArrayElements
jintArray
jint
int[]
GetLongArrayElements
jlongArray
jlong
long[]
GetFloatArrayElements
jfloatArray
jfloat
float[]
GetDoubleArrayElements
jdoubleArray
jdouble
double[]
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号