Android JNI的学习经历
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的学习经历相关推荐
- Android JNI学习(六)——Java与Native实战演习
前言: 前几篇我主要介绍了jni先关的基础知识和常用API,相信看过的童靴对JNI已经有了一定的了解,如果不了解也没关系,下面我给出了链接,可以点进去学习.接下来我将实战一个完整案例,案例很简单,就是 ...
- Android JNI学习(五)——Java与Native之间如何实现相互调用
本章将讲述Java与Native之间如何实现相互调用.我将围绕围绕如下三点来讲解. #mermaid-svg-qeVnGlVrLWrB5ryX .label{font-family:'trebuche ...
- Android JNI学习(四)——JNI的常用方法的API
前三篇主要讲解了jni基础相关的理论知识,今天主要讲解一下JNI的常用方法的API,掌握了基本的理论知识和常用的API接下来才能更好的实战. jni的常用API大纲 再看API前,我建议大家主要结合官 ...
- 一个拿到人人网和淘宝网offer的大四学生的Android学习经历
一个拿到人人网和淘宝网offer的大四学生的Android学习经历 本来早就应该整理好的,但是最近一直杂事比较多,现在在家,我家不能上网,在亲戚家用网,总算整理好了.我也着急啊.因为过几天就要去实习了 ...
- 推荐学习!2021年Android春招面试经历,系列篇
越来越多的人在提"移动端的下半场"."Android 开发的焦虑"之类的,也有人在喊"技术天天在变,学也学不完","昨天 Kotl ...
- Android音视频学习系列(六) — 掌握视频基础知识并使用OpenGL ES 2.0渲染YUV数据
系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...
- 基于 Android NDK 的学习之旅-----资源释放
基于 Android NDK 的学习之旅-----资源释放 做上一个项目的时候因为与C引擎交互频繁,有时候会突然莫名其妙的的整个应用程序直接挂掉.因为我是学Java 开始的,所以对主动释放内存没多大概 ...
- 基于 Android NDK 的学习之旅----- C调用Java
2019独角兽企业重金招聘Python工程师标准>>> 基于 Android NDK 的学习之旅----- C调用Java 许多成熟的C引擎要移植到Android 平台上使用 , 一 ...
- Android JNI开发入门之一
JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...
最新文章
- 持续集成(三):最佳实践
- python爬虫 小白轻松从0到1_如何从0到1,学习Python的流程【小白入门】
- 递归找出文件夹里面所有文件
- happiness is meaningful joy
- api 原生hbase_Hbase常用api
- 高中生计算机专业的研究论文,高中计算机个性化教学模式研究的论文
- [译]使用DOT语言和GraphvizOnline来可视化你的ASP.NETCore3.0终结点01
- golang for循环的重新认识
- python barrier_Python多线程-Barrier(障碍对象)
- php提前终止,由于最大执行时间致命错误,PHP cron作业提前终止
- tf.Variable、tf.get_variable、tf.variable_scope、tf.name_scope、random、initializer
- Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
- 电力企业信息化建设方案之调度信息报送系统
- 谷歌研究员发现新的 iOS 安全系统
- python接收前端post数据_python实现通过flask和前端进行数据收发
- Android 性能优化 (十一) 电量优化全解析 秒变大神
- C#桌面办公应用-工资管理系统系列二
- 什么才是真正的架构设计
- html转换高清pdf,html转换pdf
- 哪些是性价比高的骨传导蓝牙耳机,五款骨传导蓝牙耳机推荐