Android JNI的学习经历

  • 理解JNI
  • Java测MediaScanner的分析
    • 静态注册: 静态方法是根据函数名字建立java 和jni之间的关联
    • 动态注册的原理:java native 函数直接调用jni函数的函数指针:JNINativeMethod

理解JNI

jni是java 和c/c++ 代码调用的桥梁
Java(MediaScanner)
|
jni (libmedia_jni.so)
|
Native(libmedia.so)

Java测MediaScanner的分析

public class MediaScanner implements AutoCloseable {
static {
System.loadLibrary(“media_jni”);//加载对应的jni so
native_init();
}

静态注册: 静态方法是根据函数名字建立java 和jni之间的关联

// 关键字 native  申明一个个Native_init  函数体是在jni完成
private static native final void native_init();

// This function gets a field ID, which in turn causes class initialization.
// It is called from a static block in MediaScanner, which won’t run until the
// first time an instance of this class is used.
static void
android_media_MediaScanner_native_init(JNIEnv *env)
{
ALOGV(“native_init”);
jclass clazz = env->FindClass(kClassMediaScanner);
if (clazz == NULL) {
return;
}

fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
if (fields.context == NULL) {return;
}

}

缺点:
1 每个包含 native class 都会生成一个对应的 头文件
2 javah 生成的文件 文件名很长
3 第一次启动,速率比较慢
动态注册

静态注册的原理:javah 生成.c文件,从java函数调用jni函数 首先是根据名称来对应jni函数建立关联,然后 java native 函数通过函数指针来和jni函数建立关系

动态注册的原理:java native 函数直接调用jni函数的函数指针:JNINativeMethod

static const JNINativeMethod gMethods[] = {
{
“processDirectory”,
“(Ljava/lang/String;Landroid/media/MediaScannerClient;)V”,
(void *)android_media_MediaScanner_processDirectory
},

{"processFile","(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V",(void *)android_media_MediaScanner_processFile
},{"setLocale","(Ljava/lang/String;)V",(void *)android_media_MediaScanner_setLocale
},{"extractAlbumArt","(Ljava/io/FileDescriptor;)[B",(void *)android_media_MediaScanner_extractAlbumArt
},{"native_init","()V",(void *)android_media_MediaScanner_native_init
},{"native_setup","()V",(void *)android_media_MediaScanner_native_setup
},{"native_finalize","()V",(void *)android_media_MediaScanner_native_finalize
},

};

JNIEnv 功能是,保存了java测的函数指针,和java 对象
对象由成员函数和成员变量组成,
这就对应了两个函数
jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
取出 jmethodID:
jclass mediaScannerClientInterface = env->FindClass(kClassMediaScannerClient);
mScanFileMethodID = env->GetMethodID(
mediaScannerClientInterface,
“scanFile”,
“(Ljava/lang/String;JJZZ)V”);

mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface,"handleStringTag","(Ljava/lang/String;Ljava/lang/String;)V");mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface,"setMimeType","(Ljava/lang/String;)V");

使用 jmethodID (CallVoidMethod)

virtual status_t scanFile(const char* path, long long lastModified,
long long fileSize, bool isDirectory, bool noMedia)
{
ALOGV(“scanFile: path(%s), time(%lld), size(%lld) and isDir(%d)”,
path, lastModified, fileSize, isDirectory);

   jstring pathStr;if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {mEnv->ExceptionClear();return NO_MEMORY;}mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,fileSize, isDirectory, noMedia);mEnv->DeleteLocalRef(pathStr);return checkAndClearExceptionFromCallback(mEnv, "scanFile");

}
NativeType CallMethod(JNIEnv *env, jObject obj. jmethodID methodID,…)
NativeType CallStaticMethod(JNIEnv *env, jObject obj. jmethodID methodID,…)

以下是基于动态注册总结:
1 java 测调用native 和native调用java,都要经过jni
2 java 调用native,直接通过JMethodNative
3 native调用java测,可以使用jmethodID和jfieldID 组合使用。

Android JNI的学习经历相关推荐

  1. Android JNI学习(六)——Java与Native实战演习

    前言: 前几篇我主要介绍了jni先关的基础知识和常用API,相信看过的童靴对JNI已经有了一定的了解,如果不了解也没关系,下面我给出了链接,可以点进去学习.接下来我将实战一个完整案例,案例很简单,就是 ...

  2. Android JNI学习(五)——Java与Native之间如何实现相互调用

    本章将讲述Java与Native之间如何实现相互调用.我将围绕围绕如下三点来讲解. #mermaid-svg-qeVnGlVrLWrB5ryX .label{font-family:'trebuche ...

  3. Android JNI学习(四)——JNI的常用方法的API

    前三篇主要讲解了jni基础相关的理论知识,今天主要讲解一下JNI的常用方法的API,掌握了基本的理论知识和常用的API接下来才能更好的实战. jni的常用API大纲 再看API前,我建议大家主要结合官 ...

  4. 一个拿到人人网和淘宝网offer的大四学生的Android学习经历

    一个拿到人人网和淘宝网offer的大四学生的Android学习经历 本来早就应该整理好的,但是最近一直杂事比较多,现在在家,我家不能上网,在亲戚家用网,总算整理好了.我也着急啊.因为过几天就要去实习了 ...

  5. 推荐学习!2021年Android春招面试经历,系列篇

    越来越多的人在提"移动端的下半场"."Android 开发的焦虑"之类的,也有人在喊"技术天天在变,学也学不完","昨天 Kotl ...

  6. Android音视频学习系列(六) — 掌握视频基础知识并使用OpenGL ES 2.0渲染YUV数据

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  7. 基于 Android NDK 的学习之旅-----资源释放

    基于 Android NDK 的学习之旅-----资源释放 做上一个项目的时候因为与C引擎交互频繁,有时候会突然莫名其妙的的整个应用程序直接挂掉.因为我是学Java 开始的,所以对主动释放内存没多大概 ...

  8. 基于 Android NDK 的学习之旅----- C调用Java

    2019独角兽企业重金招聘Python工程师标准>>> 基于 Android NDK 的学习之旅----- C调用Java 许多成熟的C引擎要移植到Android 平台上使用 , 一 ...

  9. Android JNI开发入门之一

    JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...

最新文章

  1. 持续集成(三):最佳实践
  2. python爬虫 小白轻松从0到1_如何从0到1,学习Python的流程【小白入门】
  3. 递归找出文件夹里面所有文件
  4. happiness is meaningful joy
  5. api 原生hbase_Hbase常用api
  6. 高中生计算机专业的研究论文,高中计算机个性化教学模式研究的论文
  7. [译]使用DOT语言和GraphvizOnline来可视化你的ASP.NETCore3.0终结点01
  8. golang for循环的重新认识
  9. python barrier_Python多线程-Barrier(障碍对象)
  10. php提前终止,由于最大执行时间致命错误,PHP cron作业提前终止
  11. tf.Variable、tf.get_variable、tf.variable_scope、tf.name_scope、random、initializer
  12. Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
  13. 电力企业信息化建设方案之调度信息报送系统
  14. 谷歌研究员发现新的 iOS 安全系统
  15. python接收前端post数据_python实现通过flask和前端进行数据收发
  16. Android 性能优化 (十一) 电量优化全解析 秒变大神
  17. C#桌面办公应用-工资管理系统系列二
  18. 什么才是真正的架构设计
  19. html转换高清pdf,html转换pdf
  20. 哪些是性价比高的骨传导蓝牙耳机,五款骨传导蓝牙耳机推荐

热门文章

  1. 第一行代码 Android 第2版 书评
  2. 半开连接(half-open connection)
  3. 【机器学习】ensemble learning
  4. GD32驱动DS3231显示时钟踩坑记录
  5. 在Windows10下安装JDK15.0.1
  6. 计算机网络专业的自我鉴定,计算机网络技术专业自我鉴定
  7. H5 Plus移动APP开发之原理介绍-早会分享
  8. 什么是事务,事务的ACID特性
  9. python leetcode 398. Random Pick Index
  10. Linux目录的rwx权限