mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-07 20:31:02 -05:00
[ExtensionLoader] Prioritize extension classpath over app classpath (#433)
This commit is contained in:
parent
617bf491ee
commit
ab02568ac6
2 changed files with 88 additions and 2 deletions
|
@ -6,7 +6,6 @@ import android.content.pm.PackageInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.core.content.pm.PackageInfoCompat
|
import androidx.core.content.pm.PackageInfoCompat
|
||||||
import dalvik.system.PathClassLoader
|
|
||||||
import eu.kanade.domain.extension.interactor.TrustExtension
|
import eu.kanade.domain.extension.interactor.TrustExtension
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
|
@ -16,6 +15,7 @@ import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceFactory
|
import eu.kanade.tachiyomi.source.SourceFactory
|
||||||
import eu.kanade.tachiyomi.util.lang.Hash
|
import eu.kanade.tachiyomi.util.lang.Hash
|
||||||
import eu.kanade.tachiyomi.util.storage.copyAndSetReadOnlyTo
|
import eu.kanade.tachiyomi.util.storage.copyAndSetReadOnlyTo
|
||||||
|
import eu.kanade.tachiyomi.util.system.ChildFirstPathClassLoader
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
@ -272,7 +272,7 @@ internal object ExtensionLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
val classLoader = try {
|
val classLoader = try {
|
||||||
PathClassLoader(appInfo.sourceDir, null, context.classLoader)
|
ChildFirstPathClassLoader(appInfo.sourceDir, null, context.classLoader)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logcat(LogPriority.ERROR, e) { "Extension load error: $extName ($pkgName)" }
|
logcat(LogPriority.ERROR, e) { "Extension load error: $extName ($pkgName)" }
|
||||||
return LoadResult.Error
|
return LoadResult.Error
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue