代码编织梦想

@[Android JNINativeMethod介绍]

Android JNI 数据结构JNINativeMethod说明

Andoird 中使用了一种不同传统Java JNI的方式来定义其native的函数。
其中很重要的区别是Andorid使用了一种Java 和 C 函数的映射表数组,并在其中描述了函数的参数和返回值。这个数组的类型是JNINativeMethod,定义如下:

typedef struct {
  const char* name;
  const char* signature;
  void* fnPtr;
} JNINativeMethod;

  • 第一个变量name是Java中函数的名字。

  • 第二个变量signature,用字符串是描述了函数的参数和返回值,例如

"()V"
"(II)V"
"(Ljava/lang/String;Ljava/lang/String;)V"

实际上这些字符是与函数的参数类型一一对应的。

“()” 中的字符表示参数,后面的则代表返回值。例如"()V" 就表示void Func();

“(II)V” 表示 void Func(int, int);

普通类型

字符   Java类型        C类型

V      void            void
Z      jboolean        boolean
I      jint            int
J      jlong           long
D      jdouble         double
F      jfloat          float
B      jbyte           byte
C      jchar           char
S      jshort          short

数组类型

以"["开始,用两个字符表示

[I     jintArray       int[]
[F     jfloatArray     float[]
[B     jbyteArray      byte[]
[C     jcharArray      char[]
[S     jshortArray     short[]
[D     jdoubleArray    double[]
[J     jlongArray      long[]
[Z     jbooleanArray   boolean[]

上面的都是基本类型。
如果Java函数的参数是class,则以"L"开头,以";“结尾
中间是用”/" 隔开的包及类名。
而其对应的C函数名的参数则为jobject.
一个例外是String类,其对应的类为jstring

如:

Ljava/lang/String; String jstring
Ljava/net/Socket; Socket jobject
如果JAVA函数位于一个嵌入类,则用$作为类名间的分隔符。
例如 
"(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z"

ijkplayer中的定义为样例参考

static JNINativeMethod g_methods[] = {
    {
        "_setDataSource",   "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",   (void *) IjkMediaPlayer_setDataSourceAndHeaders
    },
    { "_setDataSourceFd",       "(I)V",     (void *) IjkMediaPlayer_setDataSourceFd },
    { "_setDataSource",         "(Ltv/danmaku/ijk/media/player/misc/IMediaDataSource;)V", (void *)IjkMediaPlayer_setDataSourceCallback },
    { "_setAndroidIOCallback",  "(Ltv/danmaku/ijk/media/player/misc/IAndroidIO;)V", (void *)IjkMediaPlayer_setAndroidIOCallback },

    { "_setVideoSurface",       "(Landroid/view/Surface;)V", (void *) IjkMediaPlayer_setVideoSurface },
    { "_prepareAsync",          "()V",      (void *) IjkMediaPlayer_prepareAsync },
    { "_start",                 "()V",      (void *) IjkMediaPlayer_start },
    { "_stop",                  "()V",      (void *) IjkMediaPlayer_stop },
    { "seekTo",                 "(J)V",     (void *) IjkMediaPlayer_seekTo },
    { "_pause",                 "()V",      (void *) IjkMediaPlayer_pause },
    { "isPlaying",              "()Z",      (void *) IjkMediaPlayer_isPlaying },
    { "getCurrentPosition",     "()J",      (void *) IjkMediaPlayer_getCurrentPosition },
    { "getDuration",            "()J",      (void *) IjkMediaPlayer_getDuration },
    { "_release",               "()V",      (void *) IjkMediaPlayer_release },
    { "_reset",                 "()V",      (void *) IjkMediaPlayer_reset },
    { "setVolume",              "(FF)V",    (void *) IjkMediaPlayer_setVolume },
    { "getAudioSessionId",      "()I",      (void *) IjkMediaPlayer_getAudioSessionId },
    { "native_init",            "()V",      (void *) IjkMediaPlayer_native_init },
    { "native_setup",           "(Ljava/lang/Object;)V", (void *) IjkMediaPlayer_native_setup },
    { "native_finalize",        "()V",      (void *) IjkMediaPlayer_native_finalize },

    { "_setOption",             "(ILjava/lang/String;Ljava/lang/String;)V", (void *) IjkMediaPlayer_setOption },
    { "_setOption",             "(ILjava/lang/String;J)V",                  (void *) IjkMediaPlayer_setOptionLong },

    { "_getColorFormatName",    "(I)Ljava/lang/String;",    (void *) IjkMediaPlayer_getColorFormatName },
    { "_getVideoCodecInfo",     "()Ljava/lang/String;",     (void *) IjkMediaPlayer_getVideoCodecInfo },
    { "_getAudioCodecInfo",     "()Ljava/lang/String;",     (void *) IjkMediaPlayer_getAudioCodecInfo },
    { "_getMediaMeta",          "()Landroid/os/Bundle;",    (void *) IjkMediaPlayer_getMediaMeta },
    { "_setLoopCount",          "(I)V",                     (void *) IjkMediaPlayer_setLoopCount },
    { "_getLoopCount",          "()I",                      (void *) IjkMediaPlayer_getLoopCount },
    { "_getPropertyFloat",      "(IF)F",                    (void *) ijkMediaPlayer_getPropertyFloat },
    { "_setPropertyFloat",      "(IF)V",                    (void *) ijkMediaPlayer_setPropertyFloat },
    { "_getPropertyLong",       "(IJ)J",                    (void *) ijkMediaPlayer_getPropertyLong },
    { "_setPropertyLong",       "(IJ)V",                    (void *) ijkMediaPlayer_setPropertyLong },
    { "_setStreamSelected",     "(IZ)V",                    (void *) ijkMediaPlayer_setStreamSelected },

    { "native_profileBegin",    "(Ljava/lang/String;)V",    (void *) IjkMediaPlayer_native_profileBegin },
    { "native_profileEnd",      "()V",                      (void *) IjkMediaPlayer_native_profileEnd },

    { "native_setLogLevel",     "(I)V",                     (void *) IjkMediaPlayer_native_setLogLevel },
    { "_setFrameAtTime",        "(Ljava/lang/String;JJII)V", (void *) IjkMediaPlayer_setFrameAtTime },
};

  • 第三个变量fnPtr是函数指针,指向C函数。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zymill/article/details/131026628

Android JNI(三)——JNI数据结构之JNINativeMethod-爱代码爱编程

上俩篇,我们讲了都是jni基础的原理知识以及如何使用cmake实现简单的jni。接下来本想讲解Java与Native相互调用的,但是发现Java与Native相互调用中设计了好多基础知识,其中用的比较多的就是数据结构JNINativeMethod,所以,我想单独拿出来讲一下。 什么是JNINativeMethod Andoird 中使用了一种不同传统J

android 12.0 launcher3 app列表页桌面图标按安装时间排序-爱代码爱编程

1.概述   在12.0的系统开发中,在对Launcher3进行功能开发时,系统默认的app列表页排序是安装app名称进行排序的,由于功能的需要要求按照app安装时间进行排序,这就需要找到相关的排序地方,进行排序方式的修改就能完成这个功能 2.Launcher3 app列表页桌面图标按安装时间排序的相关代码 packages/apps/L

android 12.0launcher3 禁止首屏时钟部件拖动到其他屏-爱代码爱编程

1.概述   在12.0的系统rom定制化开发中, 在系统Launcher3中,首页中间默认有个时钟部件来显示时间,并且可以任意拖拽到其他地方,如果拖动到其他屏显的很不美观,所以根据需要要求时钟部件 不能拖拽到其他屏,所以就要从拖拽开始处理,判断如果是时钟部件,就不让拖拽到其他屏,先从拖拽流程分析 2.Launcher3 禁止首屏时钟部件拖动到其他屏的

android 12.0默认授予app获取序列号serialno权限-爱代码爱编程

1. 概述 在12.0的系统rom定制化中,在一些第三方app开发中,会获取序列号等属性,而在10.0以后的高版本对于获取系统属性的相关信息要求严格 必须有权限才可以,10.0以前的Android版本中,可以直接通过调用Build.SERIAL来获取序列号,在高版本中,为了保护个人隐私, 不让第三方应用轻易获取序列号。所以该Api已经过时, 并且它的值也

android aidl及binder基础知识总结-爱代码爱编程

1、什么是binder binder是android framework提供的,用于跨进程方法调用的机制,具有安全高效等特点。 我们知道,在 Android 系统中,每个应用程序都运行在一个独立的进程中,各个进程之间需要

kotlin solid 原则-爱代码爱编程

Kotlin SOLID 原则 许多 Kotlin 开发者并不完全了解 SOLID 原理,即使他们知道,他们也不知道为什么要使用它。您准备好了解所有细节了吗? 介绍 亲爱的 Kotlin 爱好者,您好!欢迎来到我的

android 12.0 第三方输入法app设置系统默认输入法-爱代码爱编程

1.概述 在12.0的产品开发中,有功能需要要求设置默认输入法,替换掉系统的输入法,所以这就需要了解设置输入法的相关功能需求,然后根据输入法包名来设置默认输入法 2.第三方输入法app设置系统默认输入法的核心代码 frameworks/base/packages/SettingsProvider/src/com/android/providers/s

android 12.0launcher3禁止拖动图标到hotseat-爱代码爱编程

1.概述 在12.0系统Launcher3进行定制化开发中,对于hotseat的开发中,由功能需求要求禁止拖动图标到Hotseat的功能,而拖拽也是在workspace.java中处理的 接下来就从workspace.java 开始找解决的办法 2.Launcher3禁止拖动图标到Hotseat相关代码分析 packages/apps/Launche

android 12.0状态栏居中显示时间和修改时间显示样式-爱代码爱编程

1.概述 在12.0的系统rom定制化开发中,在systemui状态栏系统时间默认显示在左边和通知显示在一起,但是客户想修改显示位置,想显示在中间,所以就要修改SystemUI 的Clock.java 文件这个就是管理显示时间的,居中显示的话就得修改布局文件了 效果图如下: 在这里插入图片描述   1.布局文件的修改: frameworks/

android uevent事件分析-爱代码爱编程

1.背景概述 众所周知,在安卓系统中有状态栏,在插入外设的时候,会在顶部状态栏显示小图标。 比如,camera设备,耳机设备,U盘,以及电池等等。这些都需要在状态栏动态显示。 从上面这张图片可以看出这些设备都有自己的服务一直在跑,并且都是继承了UEventObserver.java这个类去获取kernel的Event事件。下面将着重分析UEventO

jsbridge 原理-爱代码爱编程

JSBridge 的起源 近些年,移动端普及化越来越高,开发过程中选用 Native 还是 H5 一直是热门话题。Native 和 H5 都有着各自的优缺点,为了满足业务的需要,公司实际项目的开发过程中往往会融合两者进行 Hybrid 开发。Native 和 H5 分处两地,看起来无法联系,那么如何才能让双方协同实现功能呢? 这时我们想到了 Cordo

在 andorid 上使用 ebpf 程序-爱代码爱编程

本文主要记录了笔者在 Android Studio Emulator 中测试高版本 Android Kernel 对基于 libbpf 的 CO-RE 技术支持程度的探索过程、结果和遇到的问题。 测试采用的方式是在 A

知识体系总结(六):android基础:四大组件与ui控件_android ui控件-爱代码爱编程

文章目录 Activity一个APP的启动过程基本概念总图zygote是什么?有什么作用?SystemServer是什么?有什么用,与zygote的关系是什么?为什么称为服务端对象?APP、AMS、zygote

wav 格式和音频裁剪、转码处理_wav格式的音频剪切-爱代码爱编程

文章目录 0、参考资料1、WAV 格式了解1.1 WAV 文件头1.2 RIFF Chunk 区块1.3 Format Chunk 区块1.4 Data Chunk 区块 2、音频剪裁 -> 解码

【android】handle(三)重要的知识点问答_android 多个handler-爱代码爱编程

一个线程有几个 Handler? 一个线程可以有多个Handler,并且每一个Handler都可以处理消息队列中的消息。每个Handler在创建时会与当前线程的消息队列相关联,因此可以通过Handler向该线程的消息队列发