¿Dejar de usar una aplicación desaprobada?

Continuando con mi bash de aprender Android, acabo de leer lo siguiente :

Pregunta: ¿El usuario tiene la opción de matar la aplicación a menos que pongamos una opción de menú para matarla? Si no existe tal opción, ¿cómo termina el usuario la aplicación?

Respuesta: (Romain Guy): El usuario no, el sistema maneja esto automáticamente. Para eso es el ciclo de vida de la actividad (especialmente onPause / onStop / onDestroy). No importa lo que haga, no coloque un botón de la aplicación “salir” o “salir”. Es inútil con el modelo de aplicación de Android. Esto también es contrario a cómo funcionan las aplicaciones principales.

Jeje, por cada paso que doy en el mundo de Android me encuentro con algún tipo de problema = (

Aparentemente, no puedes salir de una aplicación en Android (pero el sistema Android puede destruir tu aplicación cuando lo desees). ¿Que pasa con eso? Estoy empezando a pensar que es imposible escribir una aplicación que funcione como una “aplicación normal”, que el usuario pueda abandonar la aplicación cuando decida hacerlo. Eso no es algo que se debe confiar en el sistema operativo para hacer.

La aplicación que bash crear no es una aplicación para Android Market. No es una aplicación de “amplio uso” para el público en general, es una aplicación de negocios que se utilizará en un campo comercial muy limitado.

Realmente estaba deseando desarrollar para la plataforma Android, ya que aborda una gran cantidad de problemas que existen en Windows Mobile y .NET. Sin embargo, la última semana ha sido algo así como un desvío para mí … Espero no tener que abandonar Android, pero ahora no se ve muy bien = (

¿Hay alguna forma de que realmente abandone la aplicación?

Con el tiempo, esta será la respuesta a su pregunta, pero primero quiero abordar una serie de cuestiones que plantea en sus diversos comentarios sobre las diversas respuestas ya dadas en el momento de redactar este documento. No tengo intención de cambiar de opinión, sino que están aquí para otros que vengan a leer esta publicación en el futuro.

El punto es que no puedo permitir que Android determine cuándo terminará mi aplicación. esa debe ser la elección del usuario.

Millones de personas están perfectamente satisfechas con el modelo en el que el entorno cierra la aplicación según sea necesario. Esos usuarios simplemente no piensan en “terminar” la aplicación de Android, más de lo que piensan acerca de “terminar” una página web o “terminar” un termostato.

Los usuarios de iPhone son más o menos de la misma manera, al presionar el botón de iPhone no necesariamente “se siente” como la aplicación se terminó, ya que muchas aplicaciones de iPhone retoman donde lo dejó el usuario, incluso si la aplicación realmente se apagó (ya que solo iPhone permite una aplicación de terceros a la vez, en este momento).

Como dije antes, hay muchas cosas que suceden en mi aplicación (datos que se PUSH al dispositivo, listas con tareas que siempre deberían estar ahí, etc.).

No sé qué significa “listas con tareas que siempre deberían estar ahí”, pero los “datos que se EMPUJAN para el dispositivo” son una ficción agradable y, en cualquier caso, no se deben hacer con una actividad. Use una tarea progtwigda (a través de AlarmManager ) para actualizar sus datos y obtener la máxima confiabilidad.

Nuestros usuarios inician sesión y no pueden hacer eso cada vez que reciben una llamada telefónica y Android decide matar la aplicación.

Hay muchas aplicaciones de iPhone y Android que se ocupan de esto. Por lo general, es porque conservan las credenciales de inicio de sesión, en lugar de obligar a los usuarios a iniciar sesión cada vez de forma manual.

Por ejemplo, queremos verificar las actualizaciones al salir de la aplicación

Eso es un error en cualquier sistema operativo. Por lo que usted sabe, la razón por la cual su aplicación se está “abandonando” es porque el sistema operativo se está apagando, y luego su proceso de actualización fallará a mitad de la transmisión. En general, eso no es algo bueno. Revise las actualizaciones al inicio o revise las actualizaciones de manera totalmente asíncrona (por ejemplo, a través de una tarea progtwigda), nunca al salir.

Algunos comentarios sugieren que presionar el botón Atrás no mata a la aplicación en absoluto (ver el enlace en mi pregunta anterior).

Presionar el botón ATRÁS no “mata la aplicación”. Termina la actividad que estaba en pantalla cuando el usuario presionó el botón ATRÁS.

Solo debe finalizar cuando los usuarios quieran terminarlo, nunca de otra manera. Si no puedes escribir aplicaciones que se comporten así en Android, entonces creo que Android no se puede usar para escribir aplicaciones reales = (

Entonces tampoco pueden las aplicaciones web. O WebOS , si entiendo su modelo correctamente (aún no he tenido la oportunidad de jugar con uno). En todos esos casos, los usuarios no “cancelan” nada, simplemente se van. iPhone es un poco diferente, ya que solo permite que una cosa se ejecute a la vez (con algunas excepciones), por lo que el acto de irse implica una terminación bastante inmediata de la aplicación.

¿Hay alguna forma de que realmente abandone la aplicación?

Como todos los demás te dijeron, los usuarios (a través de BACK) o tu código (a través de finish() ) pueden cerrar tu actividad actualmente en ejecución. Los usuarios generalmente no necesitan nada más, para aplicaciones escritas correctamente, del mismo modo que no necesitan una opción de “abandono” para usar aplicaciones web.


No hay dos entornos de aplicaciones iguales, por definición. Esto significa que puede ver las tendencias en los entornos a medida que surgen otros nuevos y otros quedan enterrados.

Por ejemplo, hay un movimiento creciente para tratar de eliminar la noción del “archivo”. La mayoría de las aplicaciones web no obligan a los usuarios a pensar en archivos. Las aplicaciones de iPhone generalmente no obligan a los usuarios a pensar en los archivos. Por lo general, las aplicaciones de Android no obligan a los usuarios a pensar en los archivos. Y así.

Del mismo modo, hay un movimiento creciente para tratar de eliminar la noción de “terminar” una aplicación. La mayoría de las aplicaciones web no obligan al usuario a desconectarse, sino que implícitamente desconecta al usuario después de un período de inactividad. Lo mismo con Android y, en menor medida, iPhone (y posiblemente WebOS).

Esto requiere más énfasis en el diseño de aplicaciones, centrándose en los objectives de negocio y no se queda con un modelo de implementación vinculado a un entorno de aplicación anterior. Los desarrolladores que no tienen el tiempo o la inclinación para hacerlo se sentirán frustrados con entornos más nuevos que rompen su modelo mental existente. Esto no es culpa de ninguno de los entornos, como tampoco es culpa de una montaña por las tormentas que fluyen a su alrededor en lugar de a través de ella.

Por ejemplo, algunos entornos de desarrollo, como Hypercard y Smalltalk, tenían la aplicación y las herramientas de desarrollo mezcladas en una configuración. Este concepto no atrapó mucho, fuera de las extensiones de lenguaje de las aplicaciones (por ejemplo, VBA en Excel , Lisp en AutoCAD ). Los desarrolladores que idearon modelos mentales que suponían la existencia de herramientas de desarrollo en la propia aplicación, por lo tanto, tuvieron que cambiar su modelo o limitarse a entornos en los que su modelo sería cierto.

Entonces, cuando escribes:

Junto con otras cosas desordenadas que descubrí, creo que el desarrollo de nuestra aplicación para Android no va a suceder.

Eso parece ser lo mejor, para ti, por ahora. Del mismo modo, le aconsejaría que no intente portar su aplicación a la Web, ya que algunos de los mismos problemas que ha informado con Android también los encontrará en las aplicaciones web (por ejemplo, sin “finalización”). O, por el contrario, algún día, si transfiere su aplicación a la Web, puede descubrir que el flujo de la aplicación web puede ser una mejor opción para Android, y puede volver a visitar un puerto Android en ese momento.

Me gustaría agregar una corrección aquí para los futuros lectores de este hilo. Este matiz en particular ha escapado a mi comprensión por un largo tiempo, así que quiero asegurarme de que ninguno de ustedes cometa los mismos errores:

System.exit() no mata a tu aplicación si tienes más de una actividad en la stack. Lo que realmente ocurre es que el proceso se cancela y se reinicia inmediatamente con una actividad menos en la stack. Esto es también lo que sucede cuando su aplicación es eliminada por el cuadro de diálogo Cerrar Fuerza, o incluso cuando intenta eliminar el proceso desde DDMS. Este es un hecho completamente indocumentado, que yo sepa.

La respuesta breve es que, si desea salir de su aplicación, debe hacer un seguimiento de todas las actividades en su stack y finish() TODAS cuando el usuario quiera salir (y no, no hay forma de iterar a través de ellas). la stack de actividades, por lo que debes gestionar todo esto tú mismo). Incluso esto en realidad no mata el proceso o cualquier referencia colgante que pueda tener. Simplemente termina las actividades. Además, no estoy seguro de si Process.killProcess(Process.myPid()) funciona mejor; No lo he probado.

Si, por otro lado, está bien que tengas actividades en tu stack, hay otro método que hace las cosas muy fáciles para ti: Activity.moveTaskToBack(true) simplemente hará un seguimiento de tu proceso y mostrará la pantalla de inicio.

La respuesta larga implica la explicación de la filosofía detrás de este comportamiento. La filosofía nace de una serie de suposiciones:

  1. En primer lugar, esto solo ocurre cuando tu aplicación está en primer plano. Si está en segundo plano, el proceso terminará bien. Sin embargo, si está en primer plano, el sistema operativo asume que el usuario desea seguir haciendo lo que estaba haciendo. (Si está intentando eliminar el proceso de DDMS, primero debe presionar el botón de inicio y luego eliminarlo)
  2. También asume que cada actividad es independiente de todas las otras actividades. Esto es a menudo cierto, por ejemplo, en el caso de que su aplicación inicie la actividad del navegador, que está completamente separada y no fue escrita por usted. La actividad del navegador puede o no crearse en la misma tarea, dependiendo de sus atributos de manifiesto.
  3. Asume que cada una de tus actividades es completamente autosuficiente y puede ser eliminada / restaurada en cualquier momento. (No me gusta esta suposición en particular, ya que mi aplicación tiene muchas actividades que dependen de una gran cantidad de datos almacenados en caché, demasiado grandes para ser serializados eficientemente durante onSaveInstanceState , pero ¿qué va a hacer?) Para la mayoría de las aplicaciones de Android bien escritas esto debería ser cierto , ya que nunca se sabe cuándo se eliminará tu aplicación en segundo plano.
  4. El factor final no es tanto una suposición, sino más bien una limitación del sistema operativo: matar a la aplicación explícitamente es lo mismo que la falla de la aplicación, y también lo mismo que Android mata la aplicación para reclamar memoria. Esto culmina con nuestro golpe de gracia: dado que Android no puede decir si la aplicación salió o se colgó o se mató en segundo plano, supone que el usuario desea regresar donde lo dejó, por lo que el ActivityManager reinicia el proceso.

Cuando lo piensas, esto es apropiado para la plataforma. En primer lugar, esto es exactamente lo que sucede cuando el proceso se cancela en segundo plano y el usuario vuelve a él, por lo que debe reiniciarse donde lo dejó. En segundo lugar, esto es lo que sucede cuando la aplicación falla y presenta el temido cuadro de diálogo Forzar cierre.

Supongamos que quiero que mis usuarios puedan tomar una foto y cargarla. Lanzo la Actividad de cámara de mi actividad y le pido que devuelva una imagen. La cámara se coloca en la parte superior de mi tarea actual (en lugar de crearse en su propia tarea). Si la cámara tiene un error y falla, ¿debería ocasionar que se bloquee la aplicación? Desde el punto de vista del usuario, solo la cámara falló y deben regresar a su actividad anterior. Por lo tanto, solo reinicia el proceso con todas las mismas actividades en la stack, menos la cámara. Dado que sus actividades deben diseñarse de modo que puedan ser eliminadas y restauradas en un abrir y cerrar de ojos, esto no debería ser un problema. Desafortunadamente, no todas las aplicaciones se pueden diseñar de esa manera, por lo que es un problema para muchos de nosotros, sin importar lo que Romain Guy o cualquier otra persona le diga. Entonces, necesitamos usar soluciones temporales.

Entonces, mi último consejo:

  • No trates de matar el proceso. Llame a finish() en todas las actividades o llame a moveTaskToBack(true) .
  • Si su proceso falla o es asesinado, y si, como yo, necesita los datos que estaban perdidos en la memoria, tendrá que regresar a la actividad raíz. Para hacer esto, debe llamar a startActivity() con un Intent que contenga el indicador Intent.FLAG_ACTIVITY_CLEAR_TOP .
  • Si desea eliminar su aplicación desde la perspectiva de Eclipse DDMS, es mejor que no esté en primer plano, o se reiniciará. Primero debe presionar el botón Inicio y luego cancelar el proceso.

Todas mis aplicaciones tienen botones para salir … y recibo con frecuencia comentarios positivos de los usuarios debido a eso. No me importa si la plataforma se diseñó de forma que las aplicaciones no las necesiten. Decir “no los pongas allí” es algo ridículo. Si el usuario quiere dejar de fumar … les proporciono el acceso para hacer exactamente eso. No creo que reduzca el funcionamiento de Android y parece una buena práctica. Entiendo el ciclo de vida … y mi observación ha sido que Android no hace un buen trabajo al manejarlo … y ese es un hecho básico.

Deja de pensar en tu aplicación como una aplicación monolítica. Es un conjunto de pantallas de interfaz de usuario que el usuario puede interactuar con su “aplicación” y “funciones” proporcionadas a través de los servicios de Android.

No saber lo que su misteriosa aplicación “hace” no es realmente importante. Supongamos que entra en túneles en una intranet corporativa súper segura, realizando alguna supervisión o interacción, y permanece registrada hasta que el usuario “abandone la aplicación”. Debido a que su departamento de TI lo ordena, los usuarios deben ser muy conscientes de cuándo están dentro o fuera de la intranet. De ahí su mentalidad de que es importante que los usuarios “dejen de fumar”.

Esto es simple. Realice un servicio que incluya una notificación continua en la barra de notificaciones que diga “Estoy en la intranet o estoy corriendo”. Haga que ese servicio realice toda la funcionalidad que necesita para su aplicación. Tenga actividades que se vinculen a ese servicio para permitir que los usuarios accedan a los bits de la interfaz de usuario que necesitan para interactuar con su “aplicación”. Y tenga un menú de Android -> Salir (o cerrar sesión, o lo que sea) botón que le dice al servicio que se cierre, luego cierra la actividad en sí.

Esto es, para todos los bashs y propósitos, exactamente lo que dices que quieres. Hecho de la manera de Android. Mire Google Talk o Google Maps Navigation para ver ejemplos de esta mentalidad de “salida”. La única diferencia es que presionar el botón Atrás fuera de su actividad puede dejar su proceso de UNIX al acecho en caso de que el usuario quiera revivir su aplicación. Esto realmente no es diferente de un sistema operativo moderno que almacena en caché los archivos recientemente accedidos en la memoria. Después de salir de su progtwig de Windows, la mayoría de los recursos que necesitaba todavía están en la memoria, esperando ser reemplazados por otros recursos a medida que se cargan ahora que ya no son necesarios. Android es lo mismo.

Realmente no veo tu problema.

Esta es una discusión interesante y perspicaz con la contribución de tantos expertos. Siento que esta publicación debe enviarse desde el sitio web principal de desarrollo de Android, ya que gira en torno a uno de los diseños principales del sistema operativo Android.

También me gustaría agregar mis dos centavos aquí.

Hasta el momento, me ha impresionado la forma en que Android maneja los eventos del ciclo de vida, llevando el concepto de una experiencia similar a la web a las aplicaciones nativas.

Una vez dicho esto, sigo creyendo que debería haber un botón para salir. ¿Por qué? … no para mí, Ted o cualquiera de los gurús de la tecnología aquí, sino con el único propósito de satisfacer la demanda del usuario final.

Aunque no soy un gran admirador de Windows, pero hace mucho tiempo introdujeron un concepto al que la mayoría de los usuarios finales están acostumbrados (un botón X) … “Quiero dejar de ejecutar un widget cuando ‘I’ quiera”.

Eso no significa que alguien (¿SO, desarrollador?) Se encargará de eso a su discreción … simplemente significa “¿dónde está mi botón Rojo X al que estoy acostumbrado?”. Mi acción debería ser análoga a “finalizar una llamada al presionar un botón”, “apagar el dispositivo presionando un botón”, y así sucesivamente … es una percepción. Me trae una satisfacción per se que mi acción logre su propósito.

Aunque un desarrollador puede suplantar este comportamiento utilizando las sugerencias que se dan aquí, la percepción aún permanece, es decir, una aplicación debe dejar de funcionar completamente (ahora), por una fuente independiente (SO) confiable y neutral a pedido del usuario final.

Puede salir, ya sea presionando el botón Atrás o llamando a finish() en su Activity . Simplemente llame a finish() desde un MenuItem si desea eliminarlo explícitamente.

Romain no dice que no se puede hacer, solo que no tiene sentido: los usuarios no necesitan preocuparse por dejar o guardar su trabajo o lo que sea, ya que la forma en que funciona el ciclo de vida de la aplicación lo alienta a escribir software inteligente que guarde y restaura su estado sin importar lo que pase.

Este debate se reduce a la antigua pregunta de si los desarrolladores saben mejor o si el usuario sabe mejor. Los diseñadores profesionales en todas las áreas de factores humanos luchan con esto todos los días.

Ted ha señalado que una de las aplicaciones más descargadas en Market es el ‘App Killer’. Las personas obtienen un poco de serotonina adicional cuando abandonan las aplicaciones. Están acostumbrados a eso con una computadora de escritorio / portátil. Mantiene las cosas moviéndose rápido. Mantiene el procesador fresco y el ventilador encendido. Usa menos energía.

Cuando considera que un dispositivo móvil es un barco mucho más pequeño, puede apreciar especialmente su incentivo para “tirar por la borda lo que ya no necesita”. Ahora los desarrolladores de Android han razonado que el sistema operativo sabe mejor y que salir de una aplicación es antiguo. De todo corazón apoyo esto.

Sin embargo, también creo que no debes frustrar al usuario, incluso si esa frustración se debe a su propia ignorancia. Por eso, concluyo que tener una opción ‘Salir’ es un buen diseño, incluso si se trata principalmente de un botón placebo que no hace más que cerrar una Vista.

Ted, lo que estás tratando de lograr se puede hacer, tal vez simplemente no cómo estás pensando en este momento.

Le sugiero que lea sobre Actividades y servicios. Deje de usar el término “aplicación” y comience a referirse a los componentes, es decir, Actividad, Servicio. Creo que solo necesitas saber más sobre la plataforma Android; es un cambio en la mentalidad de una aplicación de PC estándar. El hecho de que ninguna de sus publicaciones haya tenido la palabra “Actividad” (a excepción de una frase de Preguntas Frecuentes, es decir, no sus palabras) en ellas me dice que necesita leer un poco más.

Publicación del blog Cuándo incluir un botón de salida en las aplicaciones de Android (Sugerencia: Nunca) lo explica mucho, mucho mejor que yo. Ojalá todos los desarrolladores de Android lo hayan leído ya.

Extractos:

En mi experiencia, lo que [los usuarios] realmente quieren es una forma inequívoca de garantizar que una aplicación deje de consumir recursos (batería, ciclos de CPU, transferencia de datos, etc.).

Muchos usuarios perciben que un botón de salida implementa este requisito y solicitan que se agregue. Los desarrolladores, buscando complacer a sus usuarios, agregan amablemente uno. Poco después, ambos fracasan.

  • En la mayoría de los casos, el botón de salida simplemente llama a Activity.finish() . Esto es exactamente equivalente a presionar el botón Atrás. Exactamente. Los servicios siguen funcionando y las encuestas siguen sucediendo. Los usuarios pueden pensar que han matado a la aplicación pero no lo han hecho, y pronto estarán aún más molestos.
  • El comportamiento de salida ahora es ambiguo. ¿Debería su botón de salida simplemente cerrar la Actividad o debería detener todos los Servicios, Receptores y Alarmas asociados? ¿Qué debería hacer Atrás ? ¿Qué sucede si golpean a Home en su lugar? ¿Qué sucede si tu aplicación tiene un widget? ¿Debería el botón de salida dejar de actualizar también?

La solución es hacer que el botón Atrás se comporte como esperarías que fuera el botón de salida. Mejor aún, simplemente deja de consumir recursos cuando la aplicación no esté visible.

Adelante, lee el artículo completo.

I think the point is that there is no need to quit the app unless you have buggy software. Android quits the app when the user is not using it and the device needs more memory. If you have an app that needs to run a service in the background, you will likely want a way to turn the service off.

For example, Google Listen continues to play podcast when the app is not visible. But there is always the pause button to turn the podcast off when the user is done with it. If I remember correctly, Listen, even puts a shortcut in the notification bar so you can always get to the pause button quickly. Another example is an app like a twitter app for instance which constantly polls a service on the internet. These types of apps should really allow the user to choose how often to poll the server, or whether even to poll in a background thread.

If you need to have code that runs on exit, you can override onPause(), onStop(), or onDestroy() as appropriate. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

If you are unable to fathom how to make your data/connections (and thereby your “application”) persistent, then you will be unable to do what you “need” to do with Android.

Those who do download those cutesy little App Killers usually find they do not help battery life or memory usage, but hinder the OS from doing it’s job of managing memory efficiently…

http://android-developers.blogspot.com/2010/04/multitasking-android-way.html

I would consider reading “Android Wireless Application Development” published by Addison-Wesley. I am just finishing it up and it is VERY thorough.

It appears that you have some fundamental misunderstandings of the Android platform. I too was a little frustrated at first with the application life-cycle of Android apps, but after coming to a greater understanding, I have come to really enjoy this approach. This book will answer all of your questions and much more. It really is the best resource I have found for new Android developers.

Also, I think you need to let go of a line-for-line port of the existing app. In order to port your application to the Android platform, some of the application design is going to change. The application-lifecycle used is necessary as mobile devices have very limited resources relative to desktop systems and allows Android devices to run several applications in an orderly and resource-aware fashion. Do some more in depth study of the platform, and I think you will realize that what you are wanting to do is entirely feasible. La mejor de las suertes.

By the way, I am no way affiliated with Addison-Wesley or any person or organization associated with this book. After re-reading my post I feel that I came off a little fanboyish. I just really, really enjoyed it and found it extremely helpful. 🙂

Answer: (Romain Guy): The user doesn’t, the system handles this automatically. That’s what the activity lifecycle (especially onPause/onStop/onDestroy) is for. No matter what you do, do not put a “quit” or “exit” application button. It is useless with Android’s application model. This is also contrary to how core applications work.

1: Totally exiting an application may be generally unmandatory, but it is not useless. What if windows had no exit option? System would be doggy slow as memory was full and the OS had to guess at which programs you were done with. I don’t care what Romain Guy or even Larry Page and Sergey Brin say – these are unquestionable facts: Systems run slower when they have to kill tasks to get their memory before a new app can be launched. You just can’t tell me that it doesn’t take time to kill an app! Even the light from distant stars take time… There is some use in allowing the user to fully close apps.

2: Contrary to how core applications work? What’s that supposed to mean? When I’m done running an app for now, it is no longer doing any work…It’s just waiting to be killed by the OS when its memory is needed.

In summary, there is a distinct difference between minimizing and exiting, and neither pinch hits well for the other. Do we leave a screwdriver in every screw? Or a key in every door? Do we leave all of our appliances on high until the breaker blows and we need to turn on another appliance? Do we leave the dish washer full of dishes, and only take out enough each time to make room for some new dirty ones? Do we leave all the cars running in the driveway until — oh never mind.

If the user wants to minimize an app, then the best thing is to minimize it. If a user wants to exit an app, then by all means it is best to exit.

Is it frowned on? That’s Android’s view – they frown on it. And many many independent rookie Android developers frown on it.

But when it comes right down to it, there is good coding and bad coding. There is good program flow models and there are bad program flow models.

Leaving programs in memory when the user knows they are done with them simply is not good program flow. It serves absolutely no purpose whatsoever, and it slows things down when launching new apps or when running apps allocate more memory.

It is sort of like your car: There are times when you leave it running, like stopping at a stop light, or perhaps the fast food drive through, or stopping at the ATM. But there are other situations where you do want to shut it off – like when you get to work, or the grocery store or even home.

Similarly, if you’re playing a game and the phone rings, yes. Pause the game and keep it running. But if the user is done with the game for a while, then by all means let them exit.

The exit button on some applications should be more out in front than others. Games, for example, or programs where the user is likely to want to fully exit, should have an obvious exit. Other programs, like, perhaps, email programs, where exiting is an unlikely desire (so that it can keep checking for email) — these programs should not waste prime control input screen space with an exit option, but for good program flow, it should have an exit option. What if someone decides they don’t want their mail program trying to check email when they are in poor coverage area, or maybe in a Skype call or whatever? Let them exit the email program if they want!

Suspending and exiting are two vital tasks and neither fulfills the role of the other.

Almost 99% of the time there is no need for an Android application to take over its own life cycle. Most of the time it comes down to better planning or smarter design of the application. For example, rather build an internal service (not exported) to handle downloads, etc., or design actions and tasks around user workflow.

But that being said, where there is a will there is a way. Android provides – through the android.os.Process class, a much better API than Java to control the underlying process. And unlike Java it does not treat the developer like a moron by hiding it all behind a simple java.lang.System.exit() call.

So how do you ask your application to commit suicide in Android? Well, the trick is simple:

Create your own Android application class by inheriting from the standard android.app.Application class (remember to declare it in the AndroidManifest.xml file).

Override the onCreate() method, and store the process ID which started your application:

 this.pid = android.os.Process.myPid(); // Save for later use. 

Now to kill your application, provide a kill() method:

 android.os.Process.sendSignal(pid, android.os.Process.SIGNAL_KILL); 

Now whenever you need your app to commit suicide just type cast the application context, and call your kill method!

 ((MySuicidalApp) context.getApplicationContext()).kill() 

Just remember that due to the process management policies in Android, specifically related to services, Android may just opt to restart your service (see You should not use task killers on Android ).

When I conceive an application in Android, I see it this way:

  • You are working with your application
  • The phone rang
  • You take the call
  • At the end of the call, you come back to your application at the same place you were

To do that, you only need the Back button or the Home button of your phone (either by short or long press) and the notification bar.

When I exit my application, I only use the Back button until I am out of it or the Home button.

That’s how most of the applications are conceived I think. But if I need some sort of session or connection, I made it clear to the user with a login/logout button and notification (title bar or anything else). This is a rather different style than the pure “exit” style application.

On PCs, you have a multi-GUI desktop, and on Android, you obviously have multi-tasks, but you only display one app at a time (I don’t consider widgets here ^^). And on a mobile phone, at anytime, you could have a notification for something more important than what you are doing.

So the whole concept of an application rely on something different that “enter application – work – exit application”.

Hmmmm…

I think that you just don’t see the Android app the right way. You can do something almost like what you want easily:

  • Do the app activities save/restre state like it is encouraged in the developer livecycle documentation.

  • If some login is needed at the restre stage (no login/session information available) then do it.

  • Eventually add a button/menu/timeout in which case you will do a finish() without saving the login and other session info, making implicitly the end of app session: so if the app is started/brought to front again it will start a new session.

That way you don’t really care if the app is really removed from memory or not.

If you really want to remove it from memory (this is discouraged, and BTW for what purpose?) you can kill it conditionally at the end of onDestroy() with java.lang.System.exit(0) (or perhaps restartPackage(..) ?). Of course do it only in the case where you want to “really end the app”, because the onDestroy() is part of the normal lifecycle of activities and not an app end at all.

As an Application in an Android context is just a bunch of vaguely related Activities, quitting an Application doesn’t really make much sense. You can finish() an Activity, and the view of the previous Activity in the Activity stack will be drawn.

The Linux kernel has a feature called Out-of-memory killer (as mentioned above, the policies are configurable at the userspace level as well as the kernel is not an optimal one, but by no means unnecessary).

And it is heavily used by Android:

  • OOM killer is not for userspace

  • Android Notes (OOM Killer Info – where you can configure the OOM feature on Android)

  • Android Porting On Real Target

Some userspace apps are available to assist with these kill apps, for example:

  • Autokiller/Configuring Android’s internal task killer

You apparently have found the answer you want in the finish() command. This will not remove your app from memory, but Android will do so whenever it needs the resources, so it doesn’t make any difference that you won’t be doing that explicitly.

I would only add that in order to attain the full effect that an application exit would typically have, you would want to reset the app’s state to whatever its state is normally at the time it is first run after a boot of the device, just prior to calling finish() on all of your activities. That way, if the user selects your app again, it will appear to have been run “fresh,” without any state left over from the point prior to the simulated “exit.”

If there are some special actions that should only occur on “exit,” such as saving the user’s work or whatever, you can also perform them prior to the re-initialization part of the above routine.

This approach allows you to accomplish your goal of having an “exit” command without violating Android’s philosophy of leaving the management of OS resources, including the closing of apps, in the hands of the operating system.

Personally, I would not use this approach, because Android users expect an app to preserve its continuity when they revisit it, and so they are not used to the modality of “exiting” an app. I would instead support a “clear” function that a user can invoke to reset the app to some default initial state, without the necessity of “leaving” it in the process.

The one exception would be when the user has hit the back button a sufficient number of times to cause the app to close. In that situation, there is no expectation on the user’s part that state will have been saved (and if there is unsaved state in the app, then you, as the developer, should have code handling the back button that detects that unsaved data, and prompts the user to save it to SharedPreferences or to a file, or to some other non-volatile medium).

Regarding system.exit(0):

If you do decide to use system.exit(0) to close your app with rude finality (eg, as a result of a final back button press), then I would warn you that although for me this “works,” and in some cases has been the only way I’ve been able to close an app without any trace of it remaining, there is one minor glitch that occurs in Jelly Bean when you use this approach.

Specifically, if you use the Recent Apps list to open your app, and then use the back button to close the app (with that close implemented via system.exit(0)), the Recent Apps list will become visible again, as it will never have been closed. If you then tap on your app’s entry in that list to run it a second time from the same, already-open, Recent Apps list, there will be no response.

I suspect that the cause of this is that the Recent Apps list is holding on to a reference to your app that has become non-functional due to your having closed the app using system.exit(0). A more civilized closing of your app using finish() might have informed the OS in a manner that would have allowed it to refresh its Recent Apps list, but system.exit(0) apparently does not do this.

This is not a huge problem in and of itself, as very few people will open an app from Recent Apps, then exit it, and then immediately open it again from the same open Recent Apps list. And if they tap the home button and then re-open the Recent Apps list, your app’s entry will be there, and it will be fully functional. But I think that it shows that the use of system.exit(0) can interfere with proper communication between your app and the OS, and this suggests that there may be other, more serious, possibly subtle, consequences of using this approach.

I agree with Ted. I understand that exiting the application is not the “Android way”, but it doesn’t seem like it should be precluded. Here are three reasons why you might want a real exit to the application (not just the activity):

  1. The user might want some control over which app gets killed in the case of low memory. If important app A is running in the background, then you might like to exit app B when you are done with it so that app A doesn’t get killed by the operating system.

  2. If your application has sensitive data cached in memory, you might like to kill the app so that a virus/worm/rogue app can’t get at it. I know the security model is supposed to prevent that, but just in case…

  3. If your application uses resources (like network, CPU, sensors, etc.) that could adversely affect the phone, then one way of ensuring that those resources are freed up is to exit the application. I understand that well-behaved apps should free up resources when they are not needed. But again, exiting the application seems like a reasonable way of ensuring that.

There is a (relatively) simple design which will allow you to get around the “exit” conundrum. Make your app have a “base” state (activity) which is just a blank screen. On the first onCreate of the activity, you can launch another activity that your app’s main functionality is in. The “exit” can then be accomplished by finish()ing this second activity and going back to the base of just a blank screen. The OS can keep this blank screen in memory for as long as it wants…

In essence, because you cannot exit out to OS, you simply transform into a self-created nothingness.

I hope things will change over time. The user should be able to kill an app or process if the app process is sandboxed correctly by the OS. There is a notion that apps should be written perfectly or user will use only the apps that follow all SDK recommendations. I think that is a tall order.

First of all, never never never use System.exit(0). It is like making a person sleep punching him on the head!

Second: I’m facing this problem. Before sharing my solution a I want to share my thoughts.

I think that an “Exit Button” is stupid. Really really really stupid. And I think that users (consumer) that ask for an exit button for your application is stupid too. They don’t understand how the OS is working and how is managing resources (and it does a great job).

I think that if you write a good piece of code that do the right things (updates, saves, and pushes) at the right moment and conditions and using the correct things (Service and Receiver) it will work pretty well and no one will complain.

But to do that you have to study and learn how things works on Android. Anyway, this is my solution to provide to users an “Exit Button”.

I created an Options Menu always visible in each activity (I’ve a super activity that do that).

When the user clicks on that button this is what happens:

 Intent intent = new Intent(this, DashBoardActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); SharedPreferences settings = getSharedPreferences(getString(PREF_ID), Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean(FORCE_EXIT_APPLICATION, true); // Commit the edits! editor.commit(); startActivity(intent); finish(); 

So I’m saving in SharedPreferences that I want to kill my app, and I start an Intent. Please look at those flags; those will clear all my backstack calling my DashBoard Activity that is my “home” activity.

So in my Dashboard Activity I run this method in the onResume:

 private void checkIfForceKill() { // CHECK IF I NEED TO KILL THE APP // Restore preferences SharedPreferences settings = getSharedPreferences( getString(MXMSettingHolder.PREF_ID), Context.MODE_PRIVATE); boolean forceKill = settings.getBoolean( MusicSinglePaneActivity.FORCE_EXIT_APPLICATION, false); if (forceKill) { //CLEAR THE FORCE_EXIT SETTINGS SharedPreferences.Editor editor = settings.edit(); editor.putBoolean(FORCE_EXIT_APPLICATION, false); // Commit the edits! editor.commit(); //HERE STOP ALL YOUR SERVICES finish(); } } 

And it will work pretty well.

The only thing that I don’t understand why it’s happening is that when I do the last finish (and I’ve checked: it’s following all the correct flow of onPause → onStop → onDestroy) the application is still on the recent activity (but it’s blank).

It seems like the latest intent (that has started the DashboardActivity) is still in the system.

I’ve to dig more in order to also remove it.

Without an exit function for the application developer to kill their own application it is very bad design.

My application needs to allow the user to dynamically change data dynamically during runtime and the user needs to restart my application to make the change effect, but Android did not allow my application restart by itself. Android OS has a very bad design application life cycle.

It took me longer to read this Q&A than to actually implement a semi-proper Android Application Lifecycle.

It’s a GPS app that polls for points and sends the current location to a webservice every few seconds using a thread… This could be polling every 5 minutes in Ted’s case for an update, then onStop can simply start the update activity Ted was soo concerned about if one was found (asynchronous Ted, don’t code like a Windows programmer or your programs will run like Windows programs … eww, it’s not that hard).

I did some initial code in onCreate to set up things for the activity lifetime, including checkUpdate.start(); :

 @Override public void onStart() { super.onStart(); isRemote = true; checkUpdate.resume(); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, luh); } @Override public void onPause() { isRemote = false; checkUpdate.suspend(); locationManager.removeUpdates(luh); super.onStop(); } 

This code may be completely wrong, but it works. This is one of my first Android applications.

Voilà, an application that doesn’t consume CPU when it’s in the background, yet is instantly ready to reopen because it is in RAM (although not holding RAM as is the Android lifecycle) … an app is always ready, it’s a phone, guys/gals. If an app was to use up all the RAM and couldn’t be shut down by the OS then the thing might stop ringing =P That’s why the OS needs to be able to close your app when it’s in the background (if your application isn’t a resource hog it won’t be closed BTW), so let’s just write better applications.

For closing an app at any point use FLAG_ACTIVITY_CLEAR_TOP flag in Intent and then system.exit();

Or there is similar way, but without system.exit() when you want to exit call this method:

 public void exit() { startActivity(new Intent(this, HomeActivity.class). setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK).putExtra(EXIT_FLAG, true)); } 

In your HomeActivity.onCreate() add following code

 protected void onCreate(Bundle savedInstanceState) { if (getIntent().getBooleanExtra(EXIT_FLAG, false)) { if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { finish(); } } ...................... 

This will work without breaking the Android life-cycle.

Every time while you move to the next page through intent, use:

 `YourActivityname.this.finish()`; 

Ejemplo:

 Intent intent = new Intent(getApplicationContext(), SMS.class); startActivity(intent); MainActivity.this.finish(); 

So that no activity will be running on background and when you want to Exit your app, use:

 MainActivity.this.finish(); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); getParent().finish(); 

This exiting worked like a charm for me 🙂

The Android application life cycle is designed for mobile phone users, not computer users.

The app life-cycle is the brutally simplistic paradigm required to turn a Linux server into a consumer appliance.

Android is Java over Linux, a real cross-platform server OS. That is how it spread so quickly. The app life-cycle encapsulates the underlying reality of the OS.

To mobile users, apps are just installed or not installed. There is no concept of running or exiting. In fact, app processes are meant to run until the OS releases them for their held resources.

Since this is Stack Overflow, anyone reading this is a computer user and must turn off 90% of their knowledge to understand the mobile app lifecycle.

In any case, if you want to terminate your application you can always call System.exit(0); .

If you have 10,20 .. multiple Activities running and you want to finish all them and exit from system.

Create a static array in application class or constants class.

Constants

 public class Constants { public static ArrayList activities = new ArrayList(); } 

MainActivity Add current activity reference in this array

activity = MainActivity.this; Constants.activities.add(activity);

 public class MainActivity extends Activity { private ImageView imageButton; private Activity activity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); activity = MainActivity.this; Constants.activities.add(activity); imageButton = (ImageView) findViewById(R.id.camera); imageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // existing app. if (Constants.activities != null) { for (int i = 0; i < Constants.activities.size(); i++) { Activity s = Constants.activities.get(i); s.finish(); } } //super.finish(); finish(); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } }); } }