Detectar el button Atrás Presionar en la vista de Android

Estoy escribiendo una aplicación de juego que usa una class ChessClock. Cada uno de los dos jugadores tiene un reloj. Los relojes se envían una secuencia de posts cada décima de segundo y, si se ejecutan, networkingucen el time restante. Cuando el time expira, el reloj llama a un método en el grupo de vista padre que detiene los relojes y establece un indicador que hace que los events táctiles adicionales sean ignorados para que los usuarios ya no puedan mover las piezas. Estoy escribiendo en kotlin, pero creo que esto también estará claro para un progtwigdor de Java:

class ChessClock : TextView { constructor(context: Context) : super(context) constructor(context:Context, p:String) : this(context) { player = p } var player = "" val RUNNING = 0 val PAUSED = 1 val IDLE = 2 val EXPIRED = 3 val mInterval = 100L var mTime = 0L // in milliseconds var mState = IDLE val mHandler = Handler() val mUpdateTimeTask = object : Runnable { override fun run() { if (mState == RUNNING) showTime() mHandler.postDelayed(this, mInterval) } } // override fun onDetachedFromWindow() { // super.onDetachedFromWindow() // stop() // } fun setTime(minutes:Long) { mTime = 1000*60*minutes // minutes to milliseconds mState = IDLE setTextColor(getResources().getColor(R.color.colorIdle)) showTime() mUpdateTimeTask.run() } fun pause() { mState = PAUSED setTextColor(getResources().getColor(R.color.colorPaused)) } fun start() { mState = RUNNING setTextColor(getResources().getColor(R.color.colorRunning)) } fun expire() { mState = EXPIRED setTextColor(getResources().getColor(R.color.colorExpinetworking)) model.timeout(player) val aboyne = parent as AboyneView aboyne.gameOver(false) } fun toggle() { if (mState == PAUSED) start() else if (mState == RUNNING) pause() } fun stop() { mHandler.removeCallbacks(mUpdateTimeTask) } fun showTime() { val tenths = (mTime % 1000) / 100 var seconds = mTime / 1000 val minutes = seconds % 3600 / 60 seconds %= 60 if (minutes >= 1) setText(String.format("%02d:%02d",minutes, seconds)) else setText(String.format("%01d:%02d:%01d",minutes, seconds, tenths)) if (mState != RUNNING) return if (mTime > 0) mTime -= mInterval else expire() } } 

Esto funciona bien, pero si el usuario presiona el button "Atrás" y luego comienza un nuevo juego, los relojes aparentemente siguen funcionando, a pesar de que se ha llamado al método "onDestroy" de la actividad. Luego, cuando el reloj en funcionamiento expira, el nuevo juego se congela a pesar de que los nuevos relojes todavía se están ejecutando.

Soy nuevo en Android y no entiendo cómo se produce esto. Pensé que los relojes se destruirían cuando la actividad fuera. He probado mis ideas sobre lo que está sucediendo con los posts de logging y he confirmado que se llaman los relojes que se ejecutan después de onDestroy. También he networkingefinido onDetachedFromWindow para detener los relojes, y hace que el problema desaparezca, pero esto es excesivo. También detendrá el reloj si el usuario recibe una llamada telefónica, ¿no es así ?, y esto no es lo que quiero.

¿Puedes sugerirme cómo lograr lo que quiero? No hay forma de acceder a los relojes de la actividad que hay? He pensado en emitir algún evento en onDestroy, y tener el ChessClock escuchándolo, pero todavía no sé cómo escribir events personalizados y oyentes. hay una manera mas facil?

No sé cómo hacerlo en Kotlin, pero en Java Puede configurar el timer ejecutando un reloj de time cada X millis y luego cancelarlo si es necesario, llamando a mTimer.cancel () Debe intentar usarlo en lugar de mHandler.postDelayed (esto, mInterval)

aquí es cómo lo haces: ¿Cómo llamar a una function después de la demora en Kotlin?

No entendía cómo las sugerencias hechas podían solucionar mi problema, pero se me ocurrió un error.

Creé una variable global BACK_BUTTON inicializada en false . En la actividad, onDestroy para establecer BACK_BUTTON en true . Luego modifiqué el código de ChessClock para verificar BACK_BUTTON:

 val mUpdateTimeTask = object : Runnable { override fun run() { if (BACK_BUTTON) expire() else { if (mState == RUNNING) showTime() mHandler.postDelayed(this, mInterval) } } 

No es una gran solución, pero tendrá que funcionar hasta que descubra los events personalizados. Hasta donde puedo ver, un evento personalizado y un oyente de events personalizado es la única manera limpia de hacerlo.

  • Android kotlin: no se puede leer el file de class
  • Kotlin - Función de fábrica para class con constructor privado
  • Cómo escribir el generador HTML correcto en Kotlin
  • En Kotlin, ¿cómo delegar en una interfaz y proporcionar solo un constructor público sin arguments?
  • Cómo dibujar líneas usando drawLine ()
  • Kotlin mutableMap.put devuelve nullable
  • Igualdad referencel y estructural en Kotlin
  • Parámetros de anotación Java en Kotlin
  • Interfaz de Kotlin en una class de Java: Anulación accidental
  • La ejecución de Android falló para la tarea app.compileDebugKotlin cuando se usa firebase
  • Kotlin + MVP: anulación accidental