千家信息网

在android中怎么用Java加载解析so

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,本篇文章为大家展示了在android中怎么用Java加载解析so,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。理论基础so的加载是一种解析式装载,这与dex有
千家信息网最后更新 2026年11月04日在android中怎么用Java加载解析so

本篇文章为大家展示了在android中怎么用Java加载解析so,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

理论基础

so的加载是一种解析式装载,这与dex有一定区别,dex是先加载进行优化验证生成odex,再去解析odex文件,而so更像边解析边装载,在加载过程中主要解析是load段。
下面主要是以java层的so加载进行从源码上进行解析加载流程。

java层的so加载流程分析

System.loadLibrary入口点

在java层我们知道加载so文件是通过System.loadLibrary函数其实现的,下面就以其作为入口点进行分析它的调用关系和实现。
System.loadLibrary在的函数定义系统source\libcore\luni\src\main\java\java\lang\system.java的文件中。

下面是其函数定义实现。

//参数就是要加载的so文件名称 public static void loadLibrary(String libName) {         //通过调用Runtime下面的loadLibrary函数实现         //函数有两个参数,参数1是加载的so文件名,参数2 类加载器。        Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());    }

Runtime的loadLibray解析

通过上面的System.java的loadLibrary函数我们需要继续分析Runtime.java文件中的loadLibray函数的定义实现。
Runtime的loadLibrary函数在android系统中的位置是
source\libcore\luni\src\main\java\java\lang\Runtime.java文件。

下面是Runtime的 loadLibrary函数的定义实现源码。

/*     * Searches for and loads the given shared library using the given ClassLoader.     */    void loadLibrary(String libraryName, ClassLoader loader) {        if (loader != null) {            //通过加载器去查找要加载的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".                throw new UnsatisfiedLinkError(loader + " couldn't find \"" +                                               System.mapLibraryName(libraryName) + "\"");            }            //加载so文件名            String error = doLoad(filename, loader);            if (error != null) {                throw new UnsatisfiedLinkError(error);            }            return;        }                String filename = System.mapLibraryName(libraryName);        List candidates = new ArrayList();        String lastError = null;        //循环遍历文件路径        for (String directory : mLibPaths) {            //文件路径和文件名进行拼接            String candidate = directory + filename;            candidates.add(candidate);            if (IoUtils.canOpenReadOnly(candidate)) {                String error = doLoad(candidate, loader);                if (error == null) {                    return; // We successfully loaded the library. Job done.                }                lastError = error;            }        }        if (lastError != null) {            throw new UnsatisfiedLinkError(lastError);        }        throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);    }

Runtime的doLoad解析

通过上面的Runtime的loadLibrary函数,我们看到加载so的函数是走到doLoad函数,那么我们就需要继续分析Runtime下的doload函数的定义实现。
Rutime下的doload函数在系统中的
source\libcore\luni\src\main\java\java\lang\Runtime.java文件中。

下面的代码是Runtime的doload函数的定义实现。

 private String doLoad(String name, ClassLoader loader) {        // Android apps are forked from the zygote, so they can't have a custom LD_LIBRARY_PATH,        // which means that by default an app's shared library directory isn't on LD_LIBRARY_PATH.        // The PathClassLoader set up by frameworks/base knows the appropriate path, so we can load        // libraries with no dependencies just fine, but an app that has multiple libraries that        // depend on each other needed to load them in most-dependent-first order.        // We added API to Android's dynamic linker so we can update the library path used for        // the currently-running process. We pull the desired path out of the ClassLoader here        // and pass it to nativeLoad so that it can call the private dynamic linker API.        // We didn't just change frameworks/base to update the LD_LIBRARY_PATH once at the        // beginning because multiple apks can run in the same process and third party code can        // use its own BaseDexClassLoader.        // We didn't just add a dlopen_with_custom_LD_LIBRARY_PATH call because we wanted any        // dlopen(3) calls made from a .so's JNI_OnLoad to work too.        // So, find out what the native library search path is for the ClassLoader in question...        String ldLibraryPath = null;        if (loader != null && loader instanceof BaseDexClassLoader) {            ldLibraryPath = ((BaseDexClassLoader) loader).getLdLibraryPath();        }        // nativeLoad should be synchronized so there's only one LD_LIBRARY_PATH in use regardless        // of how many ClassLoaders are in the system, but dalvik doesn't support synchronized        // internal natives.        synchronized (this) {            return nativeLoad(name, loader, ldLibraryPath);        }    }

从以上的源码实现流程分析,我们可以看出Android在java层加载so的接口是System.loadLibrary(),通过层层递进关系从而实现java层的加载so。

上述内容就是在android中怎么用Java加载解析so,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

函数 文件 分析 参数 文件名 面的 流程 源码 系统 入口 内容 就是 技能 知识 路径 装载 简明 简明扼要 两个 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡网 中智农互联网科技 国智互联网科技 科技服务与互联网 互联网科技小贷 美国互联网黑科技 互联网科技公司有哪些 互联网科技大会案例 镁科技互联网资讯平台 科技伦理 互联网公司 银川新华互联网科技职业技术培训学校图片 知域互联网科技有限公司大骗子 电子科技大学互联网创业大赛 互联网科技人工智能实验室 长沙互联网科技 互联网科技实习生岗位 启辰互联网科技 萌小萌互联网科技河南有限公司 互联网 科技节活动 微视频大赛 小牛互联网科技有限公司地址 智能科技公司是互联网公司吗 世界互联网领先科技成果 华脉科技工业互联网产品 银川新华互联网科技职业技术培训学校图片 燊美集互联网科技有限公司 四川互联网展示科技馆设计 互联网安防科技感 互联网公司属于科技吗 张家口科技产业互联网平台 科技信息时代互联网发展
0