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机制(二)相关推荐

  1. Android开发实践:Java层与Jni层的数组传递

    Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层,由Jni层的Socket代码发送出去,当然,Jni ...

  2. saf java_[原创]Android Storage Access Framework(SAF)框架实现外置SD卡的写入(JAVA层与JNI层HOOK)...

    1. 前言 之前折腾了了一下MINE模拟器,发现SDL全是在JNI层fopen操作的,而安卓的SAF则是JAVA层通过DocumentFile和docUri来实现写入的.一种方法是通过去的File D ...

  3. Android之 震动(Vibrator)如何贯通Android系统 (从硬件设计 -- 驱动 -- HAL -- JNI -- Framework -- Application)

        在Android 2.3(Gingerbread) 系统的时候,我写过一篇关于"Android 震动马达系统"的文章,当时的Linux内核还是2.6版本的.写那篇文章的目的 ...

  4. Android 4.4.2 动态添加JNI库方法记录 (一 JNI库层)

    欢迎转载,务必注明出处.http://blog.csdn.net/wang_shuai_ww/article/details/44456755 本篇是继<s5p4418 Android 4.4. ...

  5. android power 按键,Android Framework层Power键关机流程(一,Power长按键操作处理)

    一:Android处理Power按键长按操作 在Framework层中,Android4.x对Power键(KeyEvent.KEYCODE_POWER)的操作,我们从PhoneWindowManag ...

  6. Android源码分析 - Framework层的Binder(客户端篇)

    开篇 本篇以aosp分支android-11.0.0_r25作为基础解析 我们在之前的文章中,从驱动层面分析了Binder是怎样工作的,但Binder驱动只涉及传输部分,待传输对象是怎么产生的呢,这就 ...

  7. Android 底层驱动开发步骤——linux内核层、HAL层、JNI层

    1.Linux驱动实现 2.Linux内核驱动测试 3.Android HAL层实现 4.Aidl实现 5.Service java实现 6.Service jni 实现 7.注册service和jn ...

  8. Android开发如何定制framework层服务

    刚刚跨完年,新年第一篇文章,那么今天将对Android开发framework中间层的服务定制使用作个总结.首先我们先导入Android平台源码framework层的代码到开发工具eclipse中,代码 ...

  9. Android NDK开发之旅(2):一篇文章搞定Android Studio中使用CMake进行NDK/JNI开发

    Android NDK开发之旅(2):一篇文章搞定android Studio中使用CMake进行NDK/JNI开发 (码字不易,转载请声明出处:http://blog.csdn.NET/andrex ...

最新文章

  1. linux环境安装python-pip
  2. Nature大调查显示 :全球1/4博士生想换导师
  3. 容器化方案Docker的使用方法
  4. JavaScript之事件冒泡和事件捕获详细介绍
  5. GDCM:gdcm::UIDGenerator的测试程序
  6. 点分治(简要讲解 + 模板)
  7. 使用Matlab(R2018b)画复杂函数的图形(网格图meshgrid)及等高线contour
  8. 基金定投十年不止赢不止损会怎么样?
  9. 安装Lync Server 2013
  10. 常用函数的傅里叶变换汇总
  11. 被裁员后:三个月含泪啃完了1111道面试解析,再入职腾讯年薪45万
  12. 2017php最新版本,2017php受权验证系统2.6.8受权系统,真正完整可用,全新界面受权源码...
  13. Chaos Mesh® 在腾讯——腾讯互娱混沌工程实践
  14. 企业开源办公虚拟专用网工具
  15. Jquery-留言板
  16. 快速缓解过敏的简单技巧
  17. 安卓onKeyDown事件
  18. exception java .text_java.text.ParseException
  19. 大家好,介绍一下,这是我的新朋友@VP
  20. 调用android邮件程序,Android开发中怎样调用系统Email发送邮件(多种调用方式)

热门文章

  1. 给内部类对象数组属性赋值时报错:Exception in thread main java.lang.NullPointerException...
  2. 【Flask】Flask常用信号
  3. bzoj1008: [HNOI2008]越狱
  4. boost signal2 trackable
  5. Hive一些参数设置
  6. Forms Builder常用函数
  7. FASTSCRIPT脚本实现多国语言
  8. 由浅至深 谈谈.NET混淆原理 (四) -- 反混淆(原理 + 工具篇)
  9. JavaScript 与java中数组的区别
  10. nodeJs利用mongoose模块操作数据