Home Android 面试题 - 架构篇
Post
Cancel

Android 面试题 - 架构篇

1. Replugin 插件化框架基本原理

  • 如何 Hook ClassLoader?

ApplicationattachBaseContext 方法中调用 PatchClassLoaderUtils.patch(application) 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 获取 mBase.mPackageInfo
// 1. ApplicationContext - Android 2.1
// 2. ContextImpl - Android 2.2 and higher
// 3. AppContextImpl - Android 2.2 and higher
Object oPackageInfo = ReflectUtils.readField(oBase, "mPackageInfo");

...

// 获取 mPackageInfo.mClassLoader
ClassLoader oClassLoader = (ClassLoader) ReflectUtils.readField(oPackageInfo, "mClassLoader");

...

// 外界可自定义 ClassLoader 的实现,但一定要基于 RePluginClassLoader 类
ClassLoader cl = RePlugin.getConfig().getCallbacks().createClassLoader(oClassLoader.getParent(), oClassLoader);

// 将新的 ClassLoader 写入 mPackageInfo.mClassLoader
ReflectUtils.writeField(oPackageInfo, "mClassLoader", cl);

通过反射的方法将 ContextImpl.mPackageInfo.mClassLoader 修改成框架的宿主使用的 RepluginClassLoader

  • ClassLoader 的双亲委派模型 Android 中的类加载器包括:
    • BootClassLoader:这是最顶层的类加载器,它由虚拟机实现并负责加载 Java 核心类库,如 java.lang、java.util 等。它是用本地代码实现的,无法直接在应用程序中使用。
    • PathClassLoader:应用程序启动时创建的类加载器,用于加载应用程序中的类和资源,使得应用程序能够正常运行并访问自身定义的类和资源。
    • DexClassLoader:能够加载外部的 DEX 文件,并将其中的类和资源加载到应用程序的内存中。

创建一个 ClassLoader,需要使用一个已有的 ClassLoader 对象,作为新建的实例的 ParentLoader,如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * Creates a {@code PathClassLoader} that operates on a given list of files
 * and directories. This method is equivalent to calling
 * {@link #PathClassLoader(String, String, ClassLoader)} with a
 * {@code null} value for the second argument (see description there).
 *
 * @param dexPath the list of jar/apk files containing classes and
 * resources, delimited by {@code File.pathSeparator}, which
 * defaults to {@code ":"} on Android
 * @param parent the parent class loader
 */
public PathClassLoader(String dexPath, ClassLoader parent) {
    super(dexPath, null, null, parent);
}

双亲委派模型基于以下原则:当一个类加载器收到加载类的请求时,它首先会委派给其父类加载器。如果父类加载器可以找到并加载该类,那么这个过程就完成了。只有在父类加载器无法加载该类的情况下,子类加载器才会尝试加载它。

  • Replugin 中的 ClassLoader 如何实现加载插件中的类的? RepluginClassloader: 宿主 ClassLoader 继承 PathClassLoader,重写 loadClass 方法,加载类时先从插件 PluginClassLoader 加载,加载不到载从自己的 loader 中加载。Hook 应用的 ClassLoader。 PluginClassLoader:插件 ClassLoader 继承 DexClassLoader,加载插件的类。

  • Replugin 中如何启动插件 Activity? ?

  • Replugin 中 如何加载插件中的资源? ?

This post is licensed under CC BY 4.0 by the author.

Android 面试题 - 网络篇

设计模式

Comments powered by Disqus.