android: rotar la pantalla rompia la app
Al girar el movil aparecia ERR_CONNECTION_REFUSED y ahi se quedaba. La lista de configChanges estaba incompleta —faltaba smallestScreenSize, que es justo lo que cambia al rotar—, asi que Android destruia y recreaba la Activity: el WebView se perdia y volvia a cargar la URL, a veces antes de que el backend escuchara. Con la lista completa, rotar ya no recrea nada y ademas no se pierde lo que estuvieras escribiendo. Y se anade una red de seguridad que no habia: onReceivedError vuelve a esperar al backend y recarga la ultima pagina que si cargo, en vez de dejar el error de Chromium en pantalla. Cubre tres casos mas, todos comprobados en el emulador: - Matar el proceso :node con la app abierta (lo que hace Android cuando necesita memoria): antes se quedaba muerta, ahora vuelve sola en unos 19 segundos. - Cambiar de identidad, que reinicia el backend a proposito. - Arranques lentos en moviles con poca memoria. Un guard evita que se acumulen hilos esperando al mismo puerto, porque onReceivedError se dispara una vez por recurso que falle. Probado ademas: boton atras, modo avion, trim-memory RUNNING_CRITICAL y am kill con reapertura. Todo eso ya iba bien.
This commit is contained in:
parent
728f10beb0
commit
e0ff70c138
2 changed files with 35 additions and 2 deletions
|
|
@ -38,10 +38,14 @@
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:foregroundServiceType="dataSync" />
|
android:foregroundServiceType="dataSync" />
|
||||||
|
|
||||||
|
<!-- La lista de configChanges tiene que ser completa: si falta una sola (y la
|
||||||
|
que faltaba era smallestScreenSize), rotar destruye y recrea la Activity,
|
||||||
|
el WebView se pierde y vuelve a cargar la URL, a veces antes de que el
|
||||||
|
backend escuche. -->
|
||||||
<activity
|
<activity
|
||||||
android:name="net.laenre.oasis.MainActivity"
|
android:name="net.laenre.oasis.MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|screenLayout|uiMode"
|
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|density|keyboardHidden|keyboard|navigation|uiMode|fontScale|layoutDirection"
|
||||||
android:launchMode="singleTask">
|
android:launchMode="singleTask">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,27 @@ class MainActivity : AppCompatActivity() {
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, u))
|
startActivity(Intent(Intent.ACTION_VIEW, u))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Red de seguridad: si una pagina del backend no carga, se vuelve a esperar
|
||||||
|
* y se reintenta, en vez de dejar el ERR_CONNECTION_REFUSED de Chromium en
|
||||||
|
* pantalla. Pasa cuando el backend todavia no escucha (arranque lento), y
|
||||||
|
* tambien cuando se ha reiniciado —al cambiar de identidad, o porque Android
|
||||||
|
* mato el proceso del servicio estando en segundo plano—.
|
||||||
|
*/
|
||||||
|
override fun onPageFinished(v: WebView?, url: String?) {
|
||||||
|
// se recuerda para poder volver aqui si luego hay que reintentar
|
||||||
|
if (url != null && url.startsWith("http://127.0.0.1:3000")) lastGoodUrl = url
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceivedError(v: WebView?, req: WebResourceRequest?, err: WebResourceError?) {
|
||||||
|
if (req?.isForMainFrame != true) return // un css o una imagen no cuentan
|
||||||
|
val u = req.url ?: return
|
||||||
|
if (!isLocal(u)) return // paginas de fuera, ni tocarlas
|
||||||
|
Log.w("OasisNode", "la pagina no ha cargado (${'$'}u); reintentando")
|
||||||
|
loaded = false
|
||||||
|
waitAndLoad()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sin este WebChromeClient.onPermissionRequest, el WebView DENIEGA por defecto
|
// Sin este WebChromeClient.onPermissionRequest, el WebView DENIEGA por defecto
|
||||||
|
|
@ -155,6 +176,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
*/
|
*/
|
||||||
private var loadAttempt = 0
|
private var loadAttempt = 0
|
||||||
private var loaded = false
|
private var loaded = false
|
||||||
|
@Volatile private var waiting = false // hay un hilo esperando al backend
|
||||||
|
private var lastGoodUrl: String? = null // ultima pagina que cargo bien
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Espera a que el backend acepte conexiones y entonces carga la interfaz.
|
* Espera a que el backend acepte conexiones y entonces carga la interfaz.
|
||||||
|
|
@ -182,6 +205,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun waitAndLoad() {
|
private fun waitAndLoad() {
|
||||||
|
// onReceivedError puede dispararse varias veces seguidas (la pagina y sus
|
||||||
|
// recursos); sin esto se acumularian hilos esperando al mismo puerto
|
||||||
|
if (waiting) return
|
||||||
|
waiting = true
|
||||||
showStatus(0)
|
showStatus(0)
|
||||||
Log.i("OasisNode", "esperando al backend en 127.0.0.1:3000")
|
Log.i("OasisNode", "esperando al backend en 127.0.0.1:3000")
|
||||||
Thread {
|
Thread {
|
||||||
|
|
@ -196,14 +223,16 @@ class MainActivity : AppCompatActivity() {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
loaded = true
|
loaded = true
|
||||||
|
waiting = false
|
||||||
Log.i("OasisNode", "backend listo tras " + (i / 2) + "s, cargando interfaz")
|
Log.i("OasisNode", "backend listo tras " + (i / 2) + "s, cargando interfaz")
|
||||||
web.loadUrl(targetUrl())
|
web.loadUrl(lastGoodUrl ?: targetUrl())
|
||||||
}
|
}
|
||||||
return@Thread
|
return@Thread
|
||||||
}
|
}
|
||||||
if (i % 8 == 0) Handler(Looper.getMainLooper()).post { if (!loaded) showStatus(i) }
|
if (i % 8 == 0) Handler(Looper.getMainLooper()).post { if (!loaded) showStatus(i) }
|
||||||
Thread.sleep(500); i++
|
Thread.sleep(500); i++
|
||||||
}
|
}
|
||||||
|
waiting = false
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue