Android插件化探索与发现,腾讯字节等大厂面试真题汇总

}

DexPathList构造方法被调用的时候其实就是通过makeDexElements方法把dexPath进行遍历,依次加载每个dex文件,然后通过数组Element[]存放,而在DexPathList类的findClass调用的时候,通过遍历Element[]的dex文件,在通过DexFile类的loadClassBinaryName()来加载类,如果不为空那么代表加载成功,并且返回class,否则返回null。

下面再来看一下基类的ClassLoader是如何实现的吧

public abstract class ClassLoader {

private final ClassLoader parent;

protected Class<?> loadClass(String name, boolean resolve)

throws ClassNotFoundException{

Class c = findLoadedClass(name);

if (c == null) {

try {

if (parent != null) {

c = parent.loadClass(name, false);

} else {

c = findBootstrapClassOrNull(name);

}

} catch (ClassNotFoundException e) {

}

if (c == null) {

c = findClass(name);

}

}

return c;

}

}

这明显就是一个双亲委派模型,在类加载的时候,首先去查找这个类之前是否已经被加载过,如果加载过直接返回,否则委托父类加载器去查找,如果父类加载器找不到那么就去系统的BootstrapClass去查找,到最后还是找不到的话,那么就自己亲自上阵查找了。这样就避免了重复加载,实现了更加安全。

好了总结一下DexClassLoader的加载过程:loadClass->findClass->BaseDexClassLoader.findClass->DexPathList.findClass->loadDexFile->DexFile.loadClassBinaryName->DexFile.defineClass,大体上就这样么个过程吧。

资源加载

Android系统加载资源都是通过Resource资源对象来进行加载的,因此只需要添加资源(即apk文件)所在路径到AssetManager中,即可实现对插件资源的访问。

/**

  • Create a new AssetManager containing only the basic system assets.

  • Applications will not generally use this method, instead retrieving the

  • appropriate asset manager with {@link Resources#getAssets}. Not for

  • use by applications.

  • @hide

*/

public AssetManager() {

final ApkAssets[] assets;

synchronized (sSync) {

createSystemAssetsInZygoteLocked();

assets = sSystemApkAssets;

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

}

mObject = nativeCreate();

if (DEBUG_REFS) {

mNumRefs = 0;

incRefsLocked(hashCode());

}

// Always set the framework resources.

setApkAssets(assets, false /invalidateCaches/);

}

不难发现AssetManager的构造方法是@hide隐藏的api,所以不能直接使用,这里肯定是需要通过反射啦,不过有人说Android P不是对系统的隐藏Api做出了限制,因此插件化估计要凉凉,但是我想说现在一些主流的插件化技术基本都已经适配了Android9.0了,所以无需担心。下面先简单贴出Android资源的加载流程。关于插件化的资源加载可以参考下滴滴VirtualApk资源的加载思想 (传送门)

class ContextImpl extends Context {

//…

private ContextImpl(ContextImpl container, ActivityThread mainThread,

LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,

Display display, Configuration overrideConfigura

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值