版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/
DexClassLoader
DexClassLoader 可以加载任意路径下的 dex,或者 jar、apk、zip 文件(包含classes.dex)。常用于插件化、热修复以及 dex 加壳。
源码如下:
public class DexClassLoader extends BaseDexClassLoader {
public DexClassLoader(String dexPath, String optimizedDirectory,
String librarySearchPath, ClassLoader parent) {
super(dexPath, null, librarySearchPath, parent);
}
}
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| dexPath | String | 需要加载的 dex、apk、jar、zip 文件的路径,多个路径用 : 分隔。支持任意目录下的文件。 |
| optimizedDirectory | String | 用于存放优化后的 dex 文件(即 .odex),在 API level 26 已弃用(Android 8.0 Oreo)。 |
| librarySearchPath | String | 指定本地库(native library,.so 文件)搜索路径,多个路径用 : 分隔。 |
| parent | ClassLoader | 父类加载器,用于实现类加载的委托机制。 |
动态加载
动态加载 = 运行时按需加载代码或资源
动态加载 是实现 dex加壳、插件化、热更新、热修复 的基础。比如阿里的 AndFix 、腾讯 tinker、美团 Robust 等热修复框架的基础。
使用 DexClassLoader 加载一个外部 .dex 或 .apk 文件,然后反射调用里面的类和方法。
步骤如下:
-
准备好外部的 dex / apk / jar;
-
将它放在你 app 可以访问的路径(如 /data/data/包名/files/);
-
用 DexClassLoader 加载它;
-
使用反射调用其中的类和方法。
1. 插件工程示例
插件工程主要包含这两个类:

PluginActivity 源码:使用 Jetpack Compose 创建一个白色背景、居中显示文本的界面,文本内容为 “PluginActivity from plugin” 加上 ClassLoader 信息
package com.cyrus.example.plugin
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
class PluginActivity : ComponentActivity() {
private val TAG = "PluginActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate")
val classLoaderInfo = this.javaClass.classLoader.toString()
setContent {
PluginActivityContent(classLoaderInfo)
}
}
@Composable
fun PluginActivityContent(classLoaderInfo: String) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(horizontal = 16.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "PluginActivity from plugin\n\n$classLoaderInfo",
fontSize = 18.sp,
color = Color.Black
)
}
}
override fun onStart() {
super.onStart()
Log.d(TAG, "on

最低0.47元/天 解锁文章
1247

被折叠的 条评论
为什么被折叠?



