[ExtensionLoader] Prioritize extension classpath over app classpath (#433)

This commit is contained in:
beerpsi
2024-02-25 00:54:30 +07:00
committed by GitHub
parent 617bf491ee
commit ab02568ac6
2 changed files with 88 additions and 2 deletions
@@ -0,0 +1,86 @@
package eu.kanade.tachiyomi.util.system
import dalvik.system.PathClassLoader
import java.io.IOException
import java.io.InputStream
import java.net.URL
import java.util.Enumeration
/**
* A parent-last class loader that will try in order:
* - the system class loader
* - the child class loader
* - the parent class loader.
*/
class ChildFirstPathClassLoader(
dexPath: String,
librarySearchPath: String?,
parent: ClassLoader
) : PathClassLoader(dexPath, librarySearchPath, parent) {
private val systemClassLoader: ClassLoader? = getSystemClassLoader()
override fun loadClass(name: String?, resolve: Boolean): Class<*> {
var c = findLoadedClass(name)
if (c == null && systemClassLoader != null) {
try {
c = systemClassLoader.loadClass(name)
} catch (_: ClassNotFoundException) {}
}
if (c == null) {
c = try {
findClass(name)
} catch (_: ClassNotFoundException) {
super.loadClass(name, resolve)
}
}
if (resolve) {
resolveClass(c)
}
return c
}
override fun getResource(name: String?): URL? {
return systemClassLoader?.getResource(name)
?: findResource(name)
?: super.getResource(name)
}
override fun getResources(name: String?): Enumeration<URL> {
val systemUrls = systemClassLoader?.getResources(name)
val localUrls = findResources(name)
val parentUrls = parent?.getResources(name)
val urls = buildList {
while (systemUrls?.hasMoreElements() == true) {
add(systemUrls.nextElement())
}
while (localUrls?.hasMoreElements() == true) {
add(localUrls.nextElement())
}
while (parentUrls?.hasMoreElements() == true) {
add(parentUrls.nextElement())
}
}
return object : Enumeration<URL> {
val iterator = urls.iterator()
override fun hasMoreElements() = iterator.hasNext()
override fun nextElement() = iterator.next()
}
}
override fun getResourceAsStream(name: String?): InputStream? {
return try {
getResource(name)?.openStream()
} catch (_: IOException) {
return null
}
}
}