android jni framework,Android Framework层的JNI机制(二)
Java框架层中有很多地方使用JNI机制,每一个部分的框架层代码,都可能有与之对应的JNI库。先了解Java框架层的组成,继续看一下JNI在框架层中的使用。
Java框架层的组成
Java框架层的实体内容,主要分三个部分:
java框架库:framework.jar
java服务库:services.jar
资源包:framework-res.apk
framework.jar是系统的核心,其中定义并实现了Android中大多数的Java类,也提供作为标准接口的框架层API。
services.jar包含了一些复杂的服务,为框架层提供一部分功能的实现。服务库也具有Java框架层中一个主要的程序入口。进入此入口运行后,服务库将形成Java框架层一个在后台长时间运行的程序。
framework-res.apk,其中没有Java代码,基本由纯资源组成的包。资源包是Java框架层唯一的包含资源和工程描述文件的包,框架层所有的资源和组件定义均包含在资源包中。
Java框架层的3个库之间耦合性比较强,具有相互依赖,主要看看framework.jar和services.jar中的JNI使用情况。
1. framework.jar
框架库主要分布在frameworks/base的以下目录:
core:Android核心包。
graphics:图形处理包。
opengl:Android OpenGL 3D实现。
telephony:电话部分。
media:多媒体和音频。
wifi:无线局域网相关。
其中core是主要的目录,实现了Android系统所定义的大部分Java类。其中core目录下,jni包是同目录下java包中对应的JNI实现。我们的Log相关的Java类和JNI实现,就分别在这两个包中。上一篇写过frameworks/base/core/jni目录下的JNI实现,会生成一个libandroid_runtiem.so的动态库。并且启动zygote时,会实例化其中的AndroidRuntime.cpp类,对其中的JNI函数进行注册,所以core,media(部分),opengl等相关的JNI会在系统启动的时候进行注册。
2. services.jar
Android中Java框架层服务库部分的目录为:frameworks/base/services/java,同级目录下的Android.mk会将这个包编译,生成services.jar。
其中frameworks/base/services/java/com/android/server中只包含一个入口部分的类,其他的类在frameworks/base/services/core/java/com/android/server目录下。
services.jar中的JNI实现在frameworks/base/service/core/jni目录下,其中的内容生成名称为libandroid_servers.so的动态库,为services.jar提供本地支持。这个库在frameworks/base/services/java/SystemServer.java类中被加载。
此外,Android框架层还包含了其他JNI实现库。例如多媒体另一部分的JNI实现在frameworks/base/media/jni这个目录下(一部分在libandroid_runtime.so中),生成libmedia_jni.so,它也是为framework.jar提供部分的本地支持(media目录划在了框架层的framework.jar部分)。这个动态库是在frameworks/base/media/java/android/media/MediaPlayer.java类中加载,加载本地库后,会执行其中的JNI_OnLoad()函数,进行JNI方法的注册。也就是说,它是在我们程序中使用的时候进行加载的,谷歌工程师把它们放在这,或许是因为只在启动的时候注册必要的部分,其他部分在使用时随着加载过程进行动态注册。
例如:
frameworks/base/service/core/jni/onload.cpp中的JNI_OnLoad()函数:
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("GetEnv failed!");
return result;
}
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_ActivityManagerService(env);
register_android_server_PowerManagerService(env);
register_android_server_SerialService(env);
register_android_server_InputApplicationHandle(env);
register_android_server_InputWindowHandle(env);
register_android_server_InputManager(env);
register_android_server_LightsService(env);
register_android_server_AlarmManagerService(env);
register_android_server_UsbDeviceManager(env);
register_android_server_UsbMidiDevice(env);
register_android_server_UsbHostManager(env);
register_android_server_vr_VrManagerService(env);
register_android_server_VibratorService(env);
register_android_server_SystemServer(env);
register_android_server_location_GnssLocationProvider(env);
register_android_server_location_FlpHardwareProvider(env);
register_android_server_connectivity_Vpn(env);
register_android_server_AssetAtlasService(env);
register_android_server_ConsumerIrService(env);
register_android_server_BatteryStatsService(env);
register_android_server_hdmi_HdmiCecController(env);
register_android_server_tv_TvUinputBridge(env);
register_android_server_tv_TvInputHal(env);
register_android_server_PersistentDataBlockService(env);
register_android_server_Watchdog(env);
register_android_server_HardwarePropertiesManagerService(env);
return JNI_VERSION_1_4;
}
frameworks/base/media/jni/android_media_MediaPlayer.cpp中的JNI_OnLoad()函数:
jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("ERROR: GetEnv failed\n");
goto bail;
}
assert(env != NULL);
if (register_android_media_ImageWriter(env) != JNI_OK) {
ALOGE("ERROR: ImageWriter native registration failed");
goto bail;
}
if (register_android_media_ImageReader(env) < 0) {
ALOGE("ERROR: ImageReader native registration failed");
goto bail;
}
if (register_android_media_MediaPlayer(env) < 0) {
ALOGE("ERROR: MediaPlayer native registration failed\n");
goto bail;
}
// 省略
/* success -- return valid version number */
result = JNI_VERSION_1_4;
bail:
return result;
}
当Java层调用System.loadLibrary()方法加载动态函数库时,执行JNI_OnLoad()函数,完成各个JNI方法的动态注册,这和前面Log相关的JNI方法注册稍有不同。
android jni framework,Android Framework层的JNI机制(二)相关推荐
- Android开发实践:Java层与Jni层的数组传递
Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层,由Jni层的Socket代码发送出去,当然,Jni ...
- saf java_[原创]Android Storage Access Framework(SAF)框架实现外置SD卡的写入(JAVA层与JNI层HOOK)...
1. 前言 之前折腾了了一下MINE模拟器,发现SDL全是在JNI层fopen操作的,而安卓的SAF则是JAVA层通过DocumentFile和docUri来实现写入的.一种方法是通过去的File D ...
- Android之 震动(Vibrator)如何贯通Android系统 (从硬件设计 -- 驱动 -- HAL -- JNI -- Framework -- Application)
在Android 2.3(Gingerbread) 系统的时候,我写过一篇关于"Android 震动马达系统"的文章,当时的Linux内核还是2.6版本的.写那篇文章的目的 ...
- Android 4.4.2 动态添加JNI库方法记录 (一 JNI库层)
欢迎转载,务必注明出处.http://blog.csdn.net/wang_shuai_ww/article/details/44456755 本篇是继<s5p4418 Android 4.4. ...
- android power 按键,Android Framework层Power键关机流程(一,Power长按键操作处理)
一:Android处理Power按键长按操作 在Framework层中,Android4.x对Power键(KeyEvent.KEYCODE_POWER)的操作,我们从PhoneWindowManag ...
- Android源码分析 - Framework层的Binder(客户端篇)
开篇 本篇以aosp分支android-11.0.0_r25作为基础解析 我们在之前的文章中,从驱动层面分析了Binder是怎样工作的,但Binder驱动只涉及传输部分,待传输对象是怎么产生的呢,这就 ...
- Android 底层驱动开发步骤——linux内核层、HAL层、JNI层
1.Linux驱动实现 2.Linux内核驱动测试 3.Android HAL层实现 4.Aidl实现 5.Service java实现 6.Service jni 实现 7.注册service和jn ...
- Android开发如何定制framework层服务
刚刚跨完年,新年第一篇文章,那么今天将对Android开发framework中间层的服务定制使用作个总结.首先我们先导入Android平台源码framework层的代码到开发工具eclipse中,代码 ...
- Android NDK开发之旅(2):一篇文章搞定Android Studio中使用CMake进行NDK/JNI开发
Android NDK开发之旅(2):一篇文章搞定android Studio中使用CMake进行NDK/JNI开发 (码字不易,转载请声明出处:http://blog.csdn.NET/andrex ...
最新文章
- linux环境安装python-pip
- Nature大调查显示 :全球1/4博士生想换导师
- 容器化方案Docker的使用方法
- JavaScript之事件冒泡和事件捕获详细介绍
- GDCM:gdcm::UIDGenerator的测试程序
- 点分治(简要讲解 + 模板)
- 使用Matlab(R2018b)画复杂函数的图形(网格图meshgrid)及等高线contour
- 基金定投十年不止赢不止损会怎么样?
- 安装Lync Server 2013
- 常用函数的傅里叶变换汇总
- 被裁员后:三个月含泪啃完了1111道面试解析,再入职腾讯年薪45万
- 2017php最新版本,2017php受权验证系统2.6.8受权系统,真正完整可用,全新界面受权源码...
- Chaos Mesh® 在腾讯——腾讯互娱混沌工程实践
- 企业开源办公虚拟专用网工具
- Jquery-留言板
- 快速缓解过敏的简单技巧
- 安卓onKeyDown事件
- exception java .text_java.text.ParseException
- 大家好,介绍一下,这是我的新朋友@VP
- 调用android邮件程序,Android开发中怎样调用系统Email发送邮件(多种调用方式)
热门文章
- 给内部类对象数组属性赋值时报错:Exception in thread main java.lang.NullPointerException...
- 【Flask】Flask常用信号
- bzoj1008: [HNOI2008]越狱
- boost signal2 trackable
- Hive一些参数设置
- Forms Builder常用函数
- FASTSCRIPT脚本实现多国语言
- 由浅至深 谈谈.NET混淆原理 (四) -- 反混淆(原理 + 工具篇)
- JavaScript 与java中数组的区别
- nodeJs利用mongoose模块操作数据