Use built-in DelegateLastClassLoader for extensions (#3874)
Assisted-by: Claude:claude-opus-5
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user