perf(loader): don't block startup on bundle update if cached (#19)

This commit is contained in:
Palm 2026-02-01 17:55:54 +07:00 • committed by GitHub
commit a386e1907f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 8 deletions

View file

@ -83,9 +83,19 @@ object HookScriptLoaderModule : Module() {
runBlocking {
val ready = async { HookStateHolder.readyDeferred.join() }
val download = async { UpdaterModule.downloadScript().join() }
val isCustomUrl = UpdaterModule.isCustomUrlEnabled
awaitAll(ready, download)
if (!mainScript.exists() || isCustomUrl) {
val reason = if (isCustomUrl) "Custom URL enabled" else "Main script does not exist"
Log.i("$reason, downloading before load...")
val download =
async { UpdaterModule.downloadScript(showUpdateDialog = false).join() }
awaitAll(ready, download)
} else {
Log.i("Main script exists, updating in background...")
UpdaterModule.downloadScript(showUpdateDialog = true)
ready.await()
}
}
val loadSynchronously = args[2]

View file

@ -13,6 +13,7 @@ import io.github.revenge.xposed.Utils
import io.github.revenge.xposed.Utils.Companion.JSON
import io.github.revenge.xposed.Utils.Companion.reloadApp
import io.github.revenge.xposed.Utils.Log
import io.github.revenge.xposed.modules.bridge.BridgeModule
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
@ -42,6 +43,8 @@ data class LoaderConfig(
*/
object UpdaterModule : Module() {
private lateinit var config: LoaderConfig
val isCustomUrlEnabled: Boolean
get() = config.customLoadUrl.enabled
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private var lastActivity: WeakReference<Activity>? = null
@ -71,9 +74,15 @@ object UpdaterModule : Module() {
JSON.decodeFromString<LoaderConfig>(configFile.readText())
} else LoaderConfig()
}.getOrDefault(LoaderConfig())
BridgeModule.registerMethod("revenge.updater.clear") {
if (bundle.exists()) bundle.delete()
if (etag.exists()) etag.delete()
null
}
}
fun downloadScript(activity: Activity? = null): Job = scope.launch {
fun downloadScript(activity: Activity? = null, showUpdateDialog: Boolean = true): Job = scope.launch {
try {
HttpClient(CIO) {
expectSuccess = false
@ -108,15 +117,22 @@ object UpdaterModule : Module() {
Log.i("Bundle updated (${bytes.size} bytes)")
// This is a retry, so we show a dialog
if (activity != null) {
withContext(Dispatchers.Main) {
AlertDialog.Builder(activity).setTitle("Revenge Update Successful")
if (showUpdateDialog) {
val activity = activity ?: lastActivity?.get()
activity?.runOnUiThread {
AlertDialog.Builder(activity)
.setTitle("Revenge Update Downloaded")
.setMessage("A reload is required for changes to take effect.")
.setPositiveButton("Reload") { dialog, _ ->
reloadApp()
dialog.dismiss()
}.setCancelable(false).show()
}
.setNegativeButton("Later") { dialog, _ ->
dialog.dismiss()
}
.setCancelable(false)
.show()
}
}
}

View file

@ -9,6 +9,7 @@ import android.os.Build
import android.widget.Toast
import io.github.revenge.xposed.Module
import io.github.revenge.xposed.Utils
import io.github.revenge.xposed.Utils.Companion.reloadApp
import java.io.File
object AdditionalBridgeMethodsModule : Module() {
@ -47,6 +48,11 @@ object AdditionalBridgeMethodsModule : Module() {
file.writeText(contents as String)
}
BridgeModule.registerMethod("revenge.app.reload") {
reloadApp()
null
}
}
override fun onActivity(activity: Activity) = with(activity) {