Spanish ¿Como evitar que un servicio corriendo se cierre, cuando se libera la memoria en el celular?

mendex

New Member
Licensed User
Estimado,

Tengo un programa que ejecuta un servicio, el cual corre sin mayor problema, captura informacion y las tramiste por UDP a un servidor. Puedo realizar otra tareas con el celular, como llamar, enviar mensaje y jugar ya que la captura y envio de datos esta corriendo como servicio.

Pero cada vez que se libera la memoria ram del celular, esta aplicacion se cierra.

Como puedo evitar que el problema se cierre cada vez que se libera la memoria o como puedo realizar que se ejecute nuevamente la aplicación cuando esta fue cerrada por liberar memoria.

De antemanos muchas gracias

Saludos.
 

bgsoft

Well-Known Member
Licensed User
Hola Mendex

Supongo que cuando dices que cuando limpias la RAM la aplicación se cierra, se cierra la aplicación y el servicio. Que se cierre la aplicación es normal, que se cierre el servicio es mas raro.

Es importante entender cómo Android decide qué proceso matar cuando se tiene poca memoria.
Un proceso puede estar en uno de los tres estados siguientes:
- Primer plano - El usuario ve actualmente una de las actividades del proceso.
- Segundo Plano - Ninguna de las actividades del proceso son visibles, sin embargo hay un servicio iniciado.
- En pausa - No hay actividades visibles y sin servicios iniciados.

Los procesos en pausa son los primeros en ser matados cuando sea necesario. Si todavía no hay suficiente memoria, se mataron los procesos de fondo o segundo plano.
Por lo general no se puede matar procesos en primer plano.

Hace tiempo me encontré el problema que Android me mataba el servicio al limpiar la memoria, lo expuse en el foro general (ingles), por que para mi el problema no era que matase Android un servicio al limpiar la memoria, el problema era que volvia a entrar pero en el Sub Service_Create, con todas las variables a cero o vacias las cadenas, y lo peor era que no entraba en Sub Service_Destroy , por que si al limpiar memoria hubiese entrado aquí, era facil saber cuando te lo mataban.

Después de mucho discutir en el foro, la respuesta fue esta:

The correct statement is that there is no guarantee that Service_Destroy will be raised when the process is killed. The same is correct for Activity_Pause.

La traducción de esto de mi inglés seria:

La afirmación correcta es que no hay ninguna garantía de que Service_Destroy se activará cuando se mata el proceso. Lo mismo es correcto para Activity_Pause.

Aquí puedes seguir el post:

http://www.basic4ppc.com/android/forum/threads/curious-things-of-android.33361/#post-196593

La conclusión es clara, Android te puede matar un servicio y no activar el Sub Service_Destroy .

No desesperes, hay una solución, o mejor dicho, un “parche” para que funcione, al menos bajo mi corta experiencia en B4A, y la puse en práctica y a dia de hoy me funciona, ya que en el foro nadie supo darme una solución, pues me la busqué yo.

- No hagas llamadas al servicio por tiempos muy largos (mas de un dia)

- En el Sub Service_Start (StartingIntent AsIntent) vuelve a llamar al servicio al cabo de un tiempo con por ejemplo cualquiera de estas dos formas:

B4X:
‘ para minutos
StartServiceAt("", DateTime.Now + TiempoEnMinutos * DateTime.TicksPerMinute, True)

‘ para segundos
StartServiceAt("", DateTime.Now + TiempoEnSegundos * DateTime.TicksPerSecond, True)

Con esto, conseguiras que lo vuelva a llamar aunque lo mate Android y tu no lo veas en el Administrador de Aplicaciones/ Aplicaciones en ejecución, pero lo meterá en la agenda y lo volverá a llamar.

- En Service_Destroy mira si te matan el servicio, y si es asi lo vuelves a llamar

- Guardate en disco las variables de valor que necesitaras, por que al borrar la memoria, en alguna ocasión te reseteara todo y volvera a entrar en Sub Service_Create

Para parar el servicio, ademas de emplear:

B4X:
StopService(Nombre del Servicio)

Utiliza esto tambien para borrar la agenda :

B4X:
CancelScheduledService(Nombre del Servicio)  ' Para el  StartServiceAt

Para cazar este error y encontrar como solucionarlo me llevó bastante tiempo, y al final lo hice poniendo una traza de todo lo que hacia el servicio a fichero hasta que vi el problema, asi que entiendo lo que digo por que no fue algo que hice a la ligera.


Si quieres mas información de cómo funcionan los servicios, aquí es un buen sitio:

http://developer.android.com/guide/components/services.html



Y despues de los comentarios de arriba, veras que Android tambien puede matar un Servicio

Suerte


Saludos:
 
Last edited:

jsanchezc

Member
Licensed User
Utiliza Service.StartForeground para evitar que el sistema detenga un servicio:

Sub Service Start
Service.StartForeground(1,Notify)
../..
End Sub

Sub Service Destroy
Service.StopForeground(1)
End Sub
 

bgsoft

Well-Known Member
Licensed User
Hola

Puedes poner añadir el siguiente atributo al código del servicio:

B4X:
#StartCommandReturnValue: android.app.Service.START_STICKY

Android lo matará en un momento dado que por cuestiones de memoria lo necesite, pero lo volverá a crear al cabo de 5 segundos, es un paso intermedio entre la llamada estandar, y la que te comentó jsanchezc, quizas la ventaja de esta es que no necesita un icono en la barra de estado, esto dependerá de tu aplicación.

Saludos
 
Top