fix: MainActivity精简+frame.html骨架页[V5]标记

- 移除cacheFile逻辑,始终加载frame.html
- loadDataWithBaseURL避免WebView缓存
- frame.html添加[V5]标记区分版本
- Bridge保留(manifest/fetchText/sha256)
This commit is contained in:
LukeMackin
2026-07-22 00:43:06 +08:00
parent 4b4103cf06
commit e9bcb7d804
4 changed files with 17 additions and 52 deletions

View File

@@ -3,7 +3,6 @@ package dev.yuzu.gca
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import java.io.File import java.io.File
import java.net.HttpURLConnection import java.net.HttpURLConnection
@@ -11,29 +10,18 @@ import java.net.URL
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private val cacheFile: File by lazy { File(filesDir, "gca_hot.html") }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val wv = WebView(this).apply { val wv = WebView(this).apply {
if (0 != (applicationInfo.flags and android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE)) {
WebView.setWebContentsDebuggingEnabled(true)
}
settings.javaScriptEnabled = true settings.javaScriptEnabled = true
settings.domStorageEnabled = true settings.domStorageEnabled = true
settings.allowFileAccess = true settings.allowFileAccess = true
addJavascriptInterface(Bridge(this@MainActivity), "Android") addJavascriptInterface(Bridge(this@MainActivity), "Android")
webViewClient = object : WebViewClient() {}
if (cacheFile.exists()) { val html = assets.open("frame.html").bufferedReader().readText()
val html = cacheFile.readText() loadDataWithBaseURL("about:blank", html, "text/html", "UTF-8", null)
loadDataWithBaseURL("file:///android_asset/", html, "text/html", "UTF-8", null) Log.i(TAG, "Loaded frame.html (${html.length}B)")
Log.i(TAG, "Loaded cached HTML (${cacheFile.length()}B)")
} else {
loadUrl("file:///android_asset/index.html")
Log.i(TAG, "Loaded embedded index.html")
}
} }
setContentView(wv) setContentView(wv)
} }
@@ -41,66 +29,43 @@ class MainActivity : AppCompatActivity() {
inner class Bridge(private val ctx: MainActivity) { inner class Bridge(private val ctx: MainActivity) {
@android.webkit.JavascriptInterface @android.webkit.JavascriptInterface
fun saveCache(html: String) { fun saveCache(html: String) {
if (html.length > 500_000) { if (html.length > 500_000) { Log.w(TAG, "Cache too large"); return }
Log.w(TAG, "Cache rejected: too large (${html.length}B)") File(ctx.filesDir, "gca_hot.html").writeText(html)
return Log.i(TAG, "Saved ${html.length}B")
}
ctx.cacheFile.writeText(html)
Log.i(TAG, "Hot-update HTML saved (${html.length}B)")
} }
@android.webkit.JavascriptInterface @android.webkit.JavascriptInterface
fun clearCache() { fun clearCache() {
ctx.cacheFile.delete() File(ctx.filesDir, "gca_hot.html").delete()
Log.i(TAG, "Cache cleared")
} }
@android.webkit.JavascriptInterface @android.webkit.JavascriptInterface
fun sha256(input: String): String { fun sha256(input: String): String {
val md = java.security.MessageDigest.getInstance("SHA-256") val md = java.security.MessageDigest.getInstance("SHA-256")
val digest = md.digest(input.toByteArray(Charsets.UTF_8)) return md.digest(input.toByteArray(Charsets.UTF_8)).joinToString("") { "%02x".format(it) }
return digest.joinToString("") { "%02x".format(it) }
} }
/** Fetch manifest JSON from Gitea and return channel's section */
@android.webkit.JavascriptInterface @android.webkit.JavascriptInterface
fun fetchManifest(channel: String): String { fun fetchManifest(channel: String): String {
val manifestUrl = "https://git.childish-ghost.com/LukeMackin/Yuzu-GCA/raw/branch/main/ota/manifest.json" val url = "https://git.childish-ghost.com/LukeMackin/Yuzu-GCA/raw/branch/main/ota/manifest.json"
Log.i(TAG, "Bridge fetching $manifestUrl$channel")
return try { return try {
val conn = URL(manifestUrl).openConnection() as HttpURLConnection val conn = URL(url).openConnection() as HttpURLConnection
conn.connectTimeout = 10_000; conn.readTimeout = 10_000 conn.connectTimeout = 10000; conn.readTimeout = 10000
conn.instanceFollowRedirects = true
if (conn.responseCode != 200) throw Exception("HTTP ${conn.responseCode}")
val raw = conn.inputStream.bufferedReader().readText() val raw = conn.inputStream.bufferedReader().readText()
val json = org.json.JSONObject(raw) org.json.JSONObject(raw).getJSONObject(channel).toString()
json.getJSONObject(channel).toString() } catch (e: Exception) { """{"error":"${e.message}"}""" }
} catch (e: Exception) {
Log.e(TAG, "Bridge fetchManifest($channel) failed: ${e.message}")
"""{"error":"${e.message}"}"""
}
} }
/** Fetch text file from Gitea — proxy for version.txt etc */
@android.webkit.JavascriptInterface @android.webkit.JavascriptInterface
fun fetchText(path: String): String { fun fetchText(path: String): String {
val safe = path.replace("..", "").replace("\\", "/") val safe = path.replace("..", "").replace("\\", "/")
val url = "https://git.childish-ghost.com/LukeMackin/Yuzu-GCA/raw/branch/main/ota/$safe" val url = "https://git.childish-ghost.com/LukeMackin/Yuzu-GCA/raw/branch/main/ota/$safe"
Log.i(TAG, "Bridge fetching $url")
return try { return try {
val conn = URL(url).openConnection() as HttpURLConnection URL(url).openConnection().apply { connectTimeout = 10000; readTimeout = 10000 }
conn.connectTimeout = 10_000 .getInputStream().bufferedReader().readText()
conn.readTimeout = 10_000 } catch (e: Exception) { "ERROR: ${e.message}" }
conn.instanceFollowRedirects = true
val code = conn.responseCode
if (code != 200) throw Exception("HTTP $code")
conn.inputStream.bufferedReader().readText()
} catch (e: Exception) {
Log.e(TAG, "Bridge fetchText($path) failed: ${e.message}")
"ERROR: ${e.message}"
}
} }
} }
companion object { private const val TAG = "GCA-H5" } companion object { private const val TAG = "GCA" }
} }