java system.load分析_android中System.loadLibrary和System.load源码解析

这篇博客详细分析了在Android中`System.loadLibrary`和`System.load`方法的源码实现。文章指出,`System.loadLibrary`会先尝试从应用的库目录加载SO文件,再查找系统库目录。`System.load`则要求提供绝对路径。源码分析涉及`ClassLoader`的角色,以及动态库的查找和加载过程,包括`nativeLoad`的调用。此外,还讨论了JNI_OnLoad方法的调用及其返回值的重要性。
摘要由CSDN通过智能技术生成

一 概述

System.loadLibrary("jpeg"):加载动态库名称如libjpeg

System.load("D:\java\Test.so");记载绝对路径

二 System.load源码分析

//System类

public static void load(String filename) {

//Reflection.getCallerClass()返回的是当前调用类的字节码Class

Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);

}

//Runtime类

synchronized void load0(Class> fromClass, String filename) {

//1.判断是否是绝对路径,即路径中是否包含'/'

if (!(new File(filename).isAbsolute())) {

throw new UnsatisfiedLinkError(

"Expecting an absolute path of the library: " + filename);

}

if (filename == null) {

throw new NullPointerException("filename == null");

}

//2.调用 nativeLoad进行加载动态库,参数是文件路径和ClassLoader对象

String error = nativeLoad(filename, fromClass.getClassLoader());

if (error != null) {

throw new UnsatisfiedLinkError(error);

}

}

三 System.loadLibrary源码解析

//System类

public static void loadLibrary(String libname) {

Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);

}

//Runtime类

void loadLibrary0(Class> fromClass, String libname) {

//获取当前类的ClassLoader,在android中一般是PathClassLoader

ClassLoader classLoader = ClassLoader.getClassLoader(fromClass);

loadLibrary0(classLoader, fromClass, libname);

}

private synchronized void loadLibrary0(ClassLoader loader, Class> callerClass, String libname) {

if (libname.indexOf((int)File.separatorChar) != -1) {

throw new UnsatisfiedLinkError(

"Directory separator should not appear in library name: " + libname);

}

String libraryName = libname;

//1.判断classLoader是否为null以及是否是BootClassLoader实例

if (loader != null && !(loader instanceof BootClassLoader)) {

//2.调用classLoader.findLibrary(libraryName)方法查找so库文件

String filename = loader.findLibrary(libraryName);

if (filename == null) {

// It's not necessarily true that the ClassLoader used

// System.mapLibraryName, but the default setup does, and it's

// misleading to say we didn't find "libMyLibrary.so" when we

// actually searched for "liblibMyLibrary.so.so".

// 3.翻译:加载so的时候不要传lib以及后缀名so,否则会变成查找liblibMyLibrary.so.so

throw new UnsatisfiedLinkError(loader + " couldn't find \"" +

System.mapLibraryName(libraryName) + "\"");

}

//4.最终也会通过jni调用nativeLoad加载动态库

String error = nativeLoad(filename, loader);

if (error != null) {

throw new UnsatisfiedLinkError(error);

}

return;

}

// We know some apps use mLibPaths directly, potentially assuming it's not null.

// Initialize it here to make sure apps see a non-null value.

// 如果classLoader为null,执行的逻辑,从system.java.library中查找

getLibPaths();

String filename = System.mapLibraryName(libraryName);

// 最终还是调用nativeLoad方法。

String error = nativeLoad(filename, loader, callerClass);

if (error != null) {

throw new UnsatisfiedLinkError(error);

}

}

public static native java.lang.String mapLibraryName(java.lang.String libname);

这里根据ClassLoader是否存在分了两种情况,当ClasssLoader存在的时候通过loader的findLibrary()查看目标库所在路径,当ClassLoader不存在的时候通过mLibPaths加载路径。最终都会调用nati

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值