From 9d55efe6ecb38506f0e77311a76ace4823bddb53 Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Wed, 15 May 2019 15:12:08 +0800 Subject: [PATCH] add JNI --- .../Framework/Android 签名校验机制.md | 10 +- .../深入理解 JNI.md | 119 ++++++++++++++++++ .../MeidaScanner.png | Bin 0 -> 8625 bytes 3 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 blogs/Android/Framework/深入理解 Android 卷一/深入理解 JNI.md create mode 100644 images/Android/Framework/深入理解 Android 卷一/MeidaScanner.png diff --git a/blogs/Android/Framework/Android 签名校验机制.md b/blogs/Android/Framework/Android 签名校验机制.md index 4d704a0..5fd0283 100644 --- a/blogs/Android/Framework/Android 签名校验机制.md +++ b/blogs/Android/Framework/Android 签名校验机制.md @@ -4,11 +4,11 @@ Android 签名校验机制 v1、v2、v3 #### 目录 -2. 概述 -3. v1 -4. v2 -5. v3 -6. 参考 +1. 概述 +2. v1 +3. v2 +4. v3 +5. 参考 #### 概述 diff --git a/blogs/Android/Framework/深入理解 Android 卷一/深入理解 JNI.md b/blogs/Android/Framework/深入理解 Android 卷一/深入理解 JNI.md new file mode 100644 index 0000000..b5c2b68 --- /dev/null +++ b/blogs/Android/Framework/深入理解 Android 卷一/深入理解 JNI.md @@ -0,0 +1,119 @@ +--- +深入理解 JNI +--- + +#### 目录 + +1. 前言 +2. 实例分析之 MediaScanner +3. Java 层的 MediaScanner + +#### 前言 + +JNI 是 Java Native Interface 的缩写,中文译为 " Java 本地调用 "。通俗的说,JNI 是一种技术,通过这种技术可以做到 Java 中的函数和 C/C++ 编写的 Native 函数相互调用。 + +Android 中大量使用了 JNI 技术,本节就以 MediaScanner 来讲解 JNI。 + +#### 实例分析之 MediaScanner + +MediaScanner 是 Android 平台中多媒体系统的重要组成部分,它的功能是扫描媒体文件,得到诸如歌曲时长,歌曲信息等媒体信息,并将它们存入到媒体数据库中,以供其他应用程序使用。 + +![](https://i.loli.net/2019/05/15/5cdbab5edbb0391147.png) + +Java 世界对应的是 MediaScanner,而这个 MediaScanner 类有一些函数需要由 Native 层来实现。JNI 层对应的是 libmedia_jni.so。media_jni 是 JNI 库的名字,其中下划线前的 media 是 Native 库层的名字,这里就是 libmedia 库。下划线后的 ini 表示它是一个 JNI 库。JNI 库的名字可以随便取,但是 Android 平台基本上都是采用 “ lib模块名_jni.so “ 的命名方式。 + +从上面的分析可知:JNI 层必须实现为动态库的形式,这样 Java 虚拟机才能加载它并调用它的函数。 + +#### Java 层的 MediaScanner + +```java +public class MediaScanner implements AutoCloseable { + //1. 加载对应的 JNI 库 + static { + System.loadLibrary("media_jni"); + native_init(); + } + //... + //2. 声明 Native 函数,用 native 关键字标示,表示它将由 JNI 层完成 + private native boolean processFile(String path, String mimeType, MediaScannerClient client); + private static native final void native_init(); + +} +``` + +如果 Java 要调用 native 函数,就必须通过一个位于 JNI 层的动态库来实现。动态库就是运行时加载的库,那么在什么时候以及什么地方加载这个库呢? + +原则是是,在调用 native 函数前,任何时候、任何地方加载都可以。通常的做法是在类的 static 语句中加载,调用 System.loadLibrary 方法就可以了。其函数的参数是动态库的名字,即 media_jni。系统会自动根据不同的平台扩展成真实的动态库文件名,例如在 Linux 系统上会扩展成 libmedia_jni.so,而在 Windows 平台上则会扩展成 media_jni.dll。 + +在 Java 层使用 JNI 技术真是太容易了,只需要完成两项工作即可: + +1. 加载对应的 JNI 库 +2. 声明由关键字 native 修饰的函数 + +但是在 JNI 层,要完成的任务可没那么轻松了。 + +#### JNI 层 MeidaScanner + +看下 android.media.MediaScanner.cpp 源码: + +```c++ +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; + } +} + +static jboolean +android_media_MediaScanner_processFile( + JNIEnv *env, jobject thiz, jstring path, + jstring mimeType, jobject client) +{ + ALOGV("processFile"); + + // Lock already hold by processDirectory + MediaScanner *mp = getNativeScanner_l(env, thiz); + if (mp == NULL) { + jniThrowException(env, kRunTimeException, "No scanner available"); + return false; + } + + if (path == NULL) { + jniThrowException(env, kIllegalArgumentException, NULL); + return false; + } + + const char *pathStr = env->GetStringUTFChars(path, NULL); + if (pathStr == NULL) { // Out of memory + return false; + } + + const char *mimeTypeStr = + (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL); + if (mimeType && mimeTypeStr == NULL) { // Out of memory + // ReleaseStringUTFChars can be called with an exception pending. + env->ReleaseStringUTFChars(path, pathStr); + return false; + } + + MyMediaScannerClient myClient(env, client); + MediaScanResult result = mp->processFile(pathStr, mimeTypeStr, myClient); + if (result == MEDIA_SCAN_RESULT_ERROR) { + ALOGE("An error occurred while scanning file '%s'.", pathStr); + } + env->ReleaseStringUTFChars(path, pathStr); + if (mimeType) { + env->ReleaseStringUTFChars(mimeType, mimeTypeStr); + } + return result != MEDIA_SCAN_RESULT_ERROR; +} +``` + diff --git a/images/Android/Framework/深入理解 Android 卷一/MeidaScanner.png b/images/Android/Framework/深入理解 Android 卷一/MeidaScanner.png new file mode 100644 index 0000000000000000000000000000000000000000..c33a8ff167b5ab1391fb065d21d1cacdedc9b826 GIT binary patch literal 8625 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