Use built-in DelegateLastClassLoader for extensions (#3874)

Assisted-by: Claude:claude-opus-5
This commit is contained in:
AntsyLich
2026-08-29 22:07:51 +06:00
committed by GitHub
parent b695940114
commit 7f342ca076
3 changed files with 72 additions and 88 deletions
@@ -0,0 +1,70 @@
package mihon.data.dalvik
import android.os.Build
import dalvik.system.DelegateLastClassLoader
import dalvik.system.PathClassLoader
import java.net.URL
import java.util.Collections
import java.util.Enumeration
@Suppress("FunctionName")
fun DelegateLastClassLoaderCompat(
dexPath: String,
librarySearchPath: String?,
parent: ClassLoader,
): ClassLoader {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
DelegateLastClassLoader(dexPath, librarySearchPath, parent)
} else {
DelegateLastPathClassLoader(dexPath, librarySearchPath, parent)
}
}
/**
* Backport of [DelegateLastClassLoader], which was added in API 27.
*/
private class DelegateLastPathClassLoader(
dexPath: String,
librarySearchPath: String?,
parent: ClassLoader,
) : PathClassLoader(dexPath, librarySearchPath, parent) {
private val bootClassLoader: ClassLoader? = Any::class.java.classLoader
override fun loadClass(name: String?, resolve: Boolean): Class<*> {
findLoadedClass(name)?.let { return it }
if (bootClassLoader != null) {
try {
return bootClassLoader.loadClass(name)
} catch (_: ClassNotFoundException) {}
}
val fromSuper = try {
return findClass(name)
} catch (e: ClassNotFoundException) {
e
}
return try {
parent.loadClass(name)
} catch (_: ClassNotFoundException) {
throw fromSuper
}
}
override fun getResource(name: String?): URL? {
return bootClassLoader?.getResource(name)
?: findResource(name)
?: parent?.getResource(name)
}
override fun getResources(name: String?): Enumeration<URL> {
val resources = buildList {
bootClassLoader?.getResources(name)?.let { addAll(it.toList()) }
findResources(name)?.let { addAll(it.toList()) }
parent?.getResources(name)?.let { addAll(it.toList()) }
}
return Collections.enumeration(resources)
}
}