classloader的讲解

我们先从Activity的启动流程开始切入:

//位于android/app/ActivityThread.java中
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {// ........省略代码//通过反射创建activityjava.lang.ClassLoader cl = appContext.getClassLoader();Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);// ........省略代码}
//位于android/app/Instrumentation.java
/*** Perform instantiation of the process's {@link Activity} object.  The* default implementation provides the normal system behavior.* * @param cl The ClassLoader with which to instantiate the object.* @param className The name of the class implementing the Activity*                  object.* @param intent The Intent object that specified the activity class being*               instantiated.* * @return The newly instantiated Activity object.*/public Activity newActivity(ClassLoader cl, String className,Intent intent)throws InstantiationException, IllegalAccessException,ClassNotFoundException {String pkg = intent != null && intent.getComponent() != null? intent.getComponent().getPackageName() : null;return getFactory(pkg).instantiateActivity(cl, className, intent);}
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,@Nullable Intent intent)throws InstantiationException, IllegalAccessException, ClassNotFoundException {return (Activity) cl.loadClass(className).newInstance();}

我们通过上面代码发现最终是通过classloader.loadClass(className).newInstance()来进行Activity类的实例化的。
classloader通过java.lang.ClassLoader cl = appContext.getClassLoader()构造。

//位于android/app/ContextImpl.java
public ClassLoader getClassLoader() {return mClassLoader != null ? mClassLoader : (mPackageInfo != null ? mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader());}
//位于java/lang/ClassLoader.java
public static ClassLoader getSystemClassLoader() {return SystemClassLoader.loader;}
public abstract class ClassLoader {static private class SystemClassLoader {public static ClassLoader loader = ClassLoader.createSystemClassLoader();}private static ClassLoader createSystemClassLoader() {String classPath = System.getProperty("java.class.path", ".");String librarySearchPath = System.getProperty("java.library.path", "");return new PathClassLoader(classPath, librarySearchPath, BootClassLoader.getInstance());}
}

我们看源码发现
Activity的ClassLoader我们仔细看源码是 PathClassLoader extends BaseDexClassLoader extends ClassLoader 而loadClass这个方法在ClassLoader 中:
在这里插入图片描述
所以cl.loadClass(className)调用的流程如下:

//位于java/lang/ClassLoader.javaprotected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{// First, check if the class has already been loadedClass c = findLoadedClass(name);if (c == null) {// If still not found, then invoke findClass in order// to find the class.c = findClass(name);//这边调用findClass方法,发现这是一个protected类型方法,ClassLoader.java中没有其实现,那就是在子方法中实现了// this is the defining class loader; record the stats}return c;}

BaseDexClassLoader部分源码:

public class BaseDexClassLoader extends ClassLoader {private final DexPathList pathList;/*** Constructs an instance.** @param dexPath the list of jar/apk files containing classes and* resources, delimited by {@code File.pathSeparator}, which* defaults to {@code ":"} on Android* @param optimizedDirectory directory where optimized dex files* should be written; may be {@code null}* @param libraryPath the list of directories containing native* libraries, delimited by {@code File.pathSeparator}; may be* {@code null}* @param parent the parent class loader*/public BaseDexClassLoader(String dexPath, File optimizedDirectory,String libraryPath, ClassLoader parent) {super(parent);this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {List<Throwable> suppressedExceptions = new ArrayList<Throwable>();Class c = pathList.findClass(name, suppressedExceptions);if (c == null) {ClassNotFoundException cnfe = new ClassNotFoundException("Didn't find class \"" + name + "\" on path: " + pathList);for (Throwable t : suppressedExceptions) {cnfe.addSuppressed(t);}throw cnfe;}return c;}
}

DexPathList部分源码:

//位于/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
/*package*/ final class DexPathList {private static final String DEX_SUFFIX = ".dex";private static final String JAR_SUFFIX = ".jar";private static final String ZIP_SUFFIX = ".zip";private static final String APK_SUFFIX = ".apk";/** class definition context */private final ClassLoader definingContext;/*** List of dex/resource (class path) elements.* Should be called pathElements, but the Facebook app uses reflection* to modify 'dexElements' (http://b/7726934).*/private final Element[] dexElements;/*** Finds the named class in one of the dex files pointed at by* this instance. This will find the one in the earliest listed* path element. If the class is found but has not yet been* defined, then this method will define it in the defining* context that this instance was constructed with.** @param name of class to find* @param suppressed exceptions encountered whilst finding the class* @return the named class or {@code null} if the class is not* found in any of the dex files*/public Class findClass(String name, List<Throwable> suppressed) {for (Element element : dexElements) {DexFile dex = element.dexFile;if (dex != null) {Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);if (clazz != null) {return clazz;}}}if (dexElementsSuppressedExceptions != null) {suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));}return null;}
}

从这段源码可以看出,dexElements是用来保存dex的数组,而每个dex文件其实就是DexFile对象。遍历dexElements,然后通过DexFile去加载class文件,加载成功就返回,否则返回null。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/44836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习清单

顺序不分先后。 技术名称技术描述技术链接HTML5HTML5是下一代的HTML标准&#xff0c;是一种用于结构化内容的标记语言。MDN|HTMLCSS3CSS3是CSS技术的升级版本&#xff0c;它的最大好处就是可以让网页设计师更加方便的为网页添加各种各样的样式&#xff0c;而不用再局限于文字、…

重新认识小米

被镁光灯聚焦的企业&#xff0c;总是会被贴上各种标签。 8月14日&#xff0c;小米科技创始人雷军以“成长”为主题的年度演讲&#xff0c;刷遍社交网络。提到小米&#xff0c;你首先想到什么&#xff1f;手机发烧友、极致性价比&#xff0c;还是最年轻的500强&#xff1f; 这…

mapper.xml中循环执行多条语句时报错,但是单独拿SQL到数据库却可以执行

我是批量修改数据&#xff0c;用foreach标签包住update语句&#xff0c;报错信息如下&#xff1a; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the …

区块链应用 DApp 开发需要掌握的技能

文章目录 前言为什么要开发 DAppDApp 的优势DApp 应用范围DApp 开发者技能 前言 前面区块链系列的文章中介绍了区块链技术、智能合约、web3js&#xff0c;Solidity 编程语言&#xff0c;在开发者的角度就是要基于这些知识在Web3时代去开发一个 DApp&#xff08;去中心化应用程…

【centos】yum只下载不安装rpm包

只下载RPM包 目标机器上没有网&#xff0c;就需要先下载好再拷贝安装 reinstall&#xff1a;即使本地已经安装也要下载 &#xff08;☆推荐☆&#xff09;install&#xff1a;下载本机没有安装的包–downloadonly&#xff1a;只下载–downloaddir&#xff1a;下载到哪里&…

七夕前的爱心代码!

话不多说上代码&#xff01; import turtle as tu import random as ratu.setup(1.0, 1.0) tu.screensize(1.0, 1.0) tu.bgcolor(black) t tu.Pen() t.ht() colors [pink, hotpink, deeppink, lightpink, red, purple, violet, magenta]def draw_star(x, y, size, color):t.…

excel 动态表头与合并列

零、希望Springboot-java导出excel文件&#xff0c;包括动态表头与下边合并的列 使用 org.apache.poi 与自己封装工具类实现相关功能。代码如下 一、代码 1、依赖 implementation(group: org.apache.poi,name: poi-ooxml,version: 4.1.0)implementation(group: org.apache.po…

常见架构类型

目录 1.单机架构 2.应用数据分离架构 3.读写分离架构 4.冷热分离架构 5.垂直分库架构 6.微服务架构 7.容器编排架构 1.单机架构 单机架构是简单的将应用服务和数据库服务部署到同一台机器上。 缺点&#xff1a;存在很大的性能限制。 2.应用数据分离架构 引入负载均衡&a…

探索高级UI、源码解析与性能优化,了解开源框架及Flutter,助力Java和Kotlin筑基,揭秘NDK的魅力!

课程链接&#xff1a; 链接: https://pan.baidu.com/s/13cR0Ip6lzgFoz0rcmgYGZA?pwdy7hp 提取码: y7hp 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 --来自百度网盘超级会员v4的分享 课程介绍&#xff1a; &#x1f4da;【01】Java筑基&#xff1a;全方位指…

Dubbo高手之路3,Dubbo服务消费详解

目录 引言1. 介绍 Dubbo 服务消费的详解的目的和背景2. 概述 Dubbo 服务消费的过程和核心概念 一、Dubbo 服务消费的基础知识1. Dubbo 服务消费的架构和流程2. Dubbo 服务消费的基本配置和使用方法 二、Dubbo 服务消费的注册与发现1. Dubbo 服务消费的注册中心和发布中心的基本…

LEADTOOLS Imaging SDK Crack

LEADTOOLS Imaging SDK Crack 高级开发人员工具包包括ActiveX和WPF/XAML控件。 LEADTOOLS Imaging SDK为文件格式导入/导出、图像压缩、图像显示和效果、颜色转换、图像处理、TWAIN扫描、图像通用对话框、数据库集成、打印和互联网提供了基本和高级的彩色图像功能。 LEADTOOLS …

分布式锁实现方式

分布式锁 1 分布式锁介绍 1.1 什么是分布式 一个大型的系统往往被分为几个子系统来做&#xff0c;一个子系统可以部署在一台机器的多个 JVM(java虚拟机) 上&#xff0c;也可以部署在多台机器上。但是每一个系统不是独立的&#xff0c;不是完全独立的。需要相互通信&#xff…

奇舞周刊第503期:图解串一串 webpack 的历史和核心功能

记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ 图解串一串 webpack 的历史和核心功能 提到打包工具&#xff0c;可能你会首先想到 webpack。那没有 webpack 之前&#xff0c;都是怎么打包的呢&#xff1f;webpack 都有哪些功能&…

Framework入门03-Activity组件

3-1 说说Activity的启动流程 启动Activity会经历哪些生命周期回调 冷启动大致流程&#xff0c;涉及哪些组件&#xff0c;通信过程是怎么样的? Activity启动过程中&#xff0c;生命周期回调的原理? Activity.startActivity -> ActivityManagerNative.getDefault().star…

《游戏编程模式》学习笔记(六)单例模式 Singleton Pattern

单例模式的定义 保证一个类只有一个实例&#xff0c;并且提供了访问该实例的全局访问点。 定义这种东西一般都是不说人话的&#xff0c;要想要理解这句话的意思&#xff0c;我们得把它揉开了才能搞明白。 我们先看前半句 “保证一个类只有一个实例”&#xff0c;单例一般使用…

jenkins pipeline方式一键部署github项目

上篇&#xff1a;jenkins一键部署github项目 该篇使用jenkins pipeline-script一键部署&#xff0c;且介绍pipeline-scm jenkins环境配置 前言&#xff1a;按照上篇创建pipeline任务&#xff0c;结果报mvn&#xff0c;jdk环境不存在&#xff0c;就很疑惑&#xff0c;然后配置全…

Lemon8与中国各大社交平台的内容输出整合,将会掀起何种风浪?

近期,Lemon8迅速在北美地区展开了布局,短短几天的时间,下载量就冲到了美国APP下载总榜的前十,随后更是直登顶生活类APP首榜。作为字节跳动旗下的出海内容平台,一经问世后,就受到了大量用户的关注,并吸引了海外媒体以及营销人士的目光。那么Lemon8与中国各大社交平台的内容输出整…

实战项目:基于主从Reactor模型实现高并发服务器

项目完整代码仿mudou库one thread one loop式并发服务器实现: 仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器&#xff1a;通过模拟实现的⾼并发服务器组件&#xff0c;可以简洁快速的完成⼀个⾼性能的服务器搭建。并且&#xff0c;通过组件内提供的不同应⽤层…

开发环境搭建

Anaconda安装搭建Python环境 官网下载Anaconda anaconda官网安装Anaconda设置系统环境变量 按照实际安装路径新建填写红框环境变量 验证环境是否正常运行 WINR输入cmd conda --version python --version pip --version 显示版本信息即为正常 VSCODE Python ShiftCtrlP顶部…

第六阶|见道明心的笔墨(上)从书法之美到生活之美——林曦老师的线上直播书法课

如果你有需要&#xff0c;可以找我的&#xff0c;我这边有老师的所有课程 如果你有需要&#xff0c;可以找我的&#xff0c;我这边有老师的所有课程