android jni framework,Android Framework层的JNI机制(二)

本文深入解析了JNI在Java框架层中的应用,重点讨论了framework.jar和服务库services.jar中的JNI使用,涉及动态库的生成、系统启动时的注册过程,以及MediaPlayer和AlarmManagerService等关键组件的JNI加载机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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方法注册稍有不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值