Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo podemos evitar que un servicio muera por un sistema operativo?

Estoy usando el Service en mi aplicación y necesita funcionar hasta que se desinstale mi aplicación, pero el problema es él consigue matado por el OS.

¿Cómo podemos evitar que sea asesinado por el sistema operativo? O si se mata, ¿podemos reiniciar ese servicio de nuevo mediante programación?

  • Eclipse / Java - Valores en R.string. * Return int?
  • Debugging con Android USB en VirtualBox
  • Obtener la matriz de RadioButtons en un RadioGroup en Android
  • Capture la pantalla de Android y cree el video programáticamente
  • Tratando de implementar permisos de cámara para android M sin método virtual checkSelfPermission
  • Abrir la aplicación de Android desde la URL mediante el intento de filtro no funciona
  • Lienzo transparente de Android (vista de superficie)
  • Cómo distinguir entre el cambio de orientación y dejar la aplicación android
  • No se puede obtener el nombre de la actividad en primer plano en Android Lollipop 5.0
  • Lector de tarjetas NFC ACR 122 incompatible con Android 4.1 Jelly Beans?
  • Reiniciar SystemUI utilizando am startservice
  • Cómo hacer Visualizer mientras graba audio en android
  • 11 Solutions collect form web for “¿Cómo podemos evitar que un servicio muera por un sistema operativo?”

    Puede ejecutar el servicio en primer plano mediante startForeground () .

    Un servicio de primer plano es un servicio que se considera que es algo que el usuario está activamente consciente y por lo tanto no es un candidato para el sistema para matar cuando la memoria es baja.

    Pero tenga en cuenta que un servicio de primer plano debe proporcionar una notificación para la barra de estado ( lea aquí ) y que la notificación no puede descartarse a menos que el servicio sea detenido o eliminado del primer plano.

    Nota: Esto todavía no garantiza absolutamente que el servicio no se matará bajo condiciones de memoria extremadamente baja. Sólo hace que sea menos probable que lo maten.

    He sido perplejo por el mismo problema a la tuya recientemente.pero ahora, he encontrado una buena solución. En primer lugar, usted debe saber que, incluso su servicio fue matado por el sistema operativo, el método onCreate de su servicio sería invocado por el sistema operativo en un corto while.So puede hacer algo con el método onCreate como este:

     @Override public void onCreate() { Log.d(LOGTAG, "NotificationService.onCreate()..."); //start this service from another class ServiceManager.startService(); } @Override public void onStart(Intent intent, int startId) { Log.d(LOGTAG, "onStart()..."); //some code of your service starting,such as establish a connection,create a TimerTask or something else } 

    El contenido de "ServiceManager.startService ()" es:

     public static void startService() { Log.i(LOGTAG, "ServiceManager.startSerivce()..."); Intent intent = new Intent(NotificationService.class.getName()); context.startService(intent); } 

    Sin embargo, esta solución sólo está disponible para la situación de su servicio que está siendo asesinado por GC. Algunas veces nuestro servicio puede ser asesinado por el usuario con el Administrador de programas. En esta situación, sus prosses serán asesinados, y su servicio nunca será re-instanciado. Así que su servicio no puede ser reiniciado. Pero la buena noticia es que, cuando el PM mata su servicio, llamará a su método onDestroy. Así que podemos hacer algo con ese método.

      @Override public void onDestroy() { Intent in = new Intent(); in.setAction("YouWillNeverKillMe"); sendBroadcast(in); Log.d(LOGTAG, "onDestroy()..."); } 

    La cadena de "YouWillNeverKillMe" es una acción personalizada. Lo más importante de este método es, no agregue ningún código antes de enviar la emisión. Como el sistema no esperará la finalización de onDestroy (), debe enviar la emisión lo antes posible. A continuación, registre un receptor en manifast.xml:

     <receiver android:name=".app.ServiceDestroyReceiver" > <intent-filter> <action android:name="YouWillNeverKillMe" > </action> </intent-filter> </receiver> 

    Finalmente, cree un BroadcastReceiver, e inicie su servicio en el método onReceive:

     @Override public void onReceive(Context context, Intent intent) { Log.d(LOGTAG, "ServeiceDestroy onReceive..."); Log.d(LOGTAG, "action:" + intent.getAction()); Log.d(LOGTAG, "ServeiceDestroy auto start service..."); ServiceManager.startService(); } 

    Espero que esto sea útil para usted, y excusa mi pobre inglés escrito.

    onStartCommand() método onStartCommand() en su clase de servicio y simplemente devuelva START_STICKY (como lo sugiere "No está en blanco"). Eso es todo lo que necesitas. Si el proceso que ejecuta el servicio es eliminado (por una condición de memoria baja, por ejemplo), el sistema Android se reiniciará automáticamente (normalmente con un retraso, como 5 segundos).

    No utilice onStart() más como se sugiere en otra respuesta, está obsoleto.

    utilizar

     @Override public int onStartCommand(Intent intent, int flags, int startId) { //**Your code ** // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } 

    Ref Ciclo de vida de la documentación de Service.

    Editar método agregado.

    He encontrado otra solución del problema que garantiza que su servicio estará siempre vivo. En mi caso, este esquema resloves también el problema con FileObserver, que detiene el trabajo después de cierto período de tiempo.

    1. Utilice una actividad (StartServicesActivity) para iniciar el servicio (FileObserverService) como servicio de primer plano.
    2. Utilice la clase BroadcastReceiver (en el ejemplo CommonReceiver) para reiniciar el servicio en algunas situaciones especiales y en caso de que se haya eliminado.

    He utilizado este código en mi aplicación "Enviar imágenes automáticamente" https://play.google.com/store/apps/details?id=com.alexpap.EmailPicturesFree

    Aquí está la clase CommonReceiver.

     public class CommonReceiver extends BroadcastReceiver { public void onReceive(Context paramContext, Intent paramIntent) { paramContext.startService(new Intent(paramContext, FileObserverService.class)); } } 

    Esta es su definición en AndroidManifest.xml justo antes de la etiqueta de cierre de la aplicación.

     <receiver android:name="com.alexpap.services.CommonReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.USER_PRESENT"/> </intent-filter> </receiver> 

    Inicie el servicio en la actividad StartServicesActivity.

     Intent iFileObserver = new Intent(StartServicesActivity.this, FileObserverService.class); StartServicesActivity.this.startService(iFileObserver); 

    Aquí está onStartCommand () método del servicio.

     public int onStartCommand(Intent intent, int flags, int startId) { int res = super.onStartCommand(intent, flags, startId); /*** Put your code here ***/ startServiceForeground(intent, flags, startId); return Service.START_STICKY; } public int startServiceForeground(Intent intent, int flags, int startId) { Intent notificationIntent = new Intent(this, StartServicesActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); Notification notification = new NotificationCompat.Builder(this) .setContentTitle("File Observer Service") .setContentIntent(pendingIntent) .setOngoing(true) .build(); startForeground(300, notification); return START_STICKY; } 

    He probado este código con la aplicación Task Killer, y cada vez que el servicio fue eliminado, se reinició de nuevo casi de inmediato (realiza onStartCommand ()). Se reinicia también cada vez que enciende el teléfono y después de reiniciar. Yo uso este código en mi aplicación, que envía por correo electrónico cada foto que tomas con tu teléfono a la lista predefinida de correos electrónicos. El correo electrónico de envío y la lista de correos electrónicos recibidos se establecen en otra actividad y se almacenan en Preferencias compartidas. Tomé cerca de 100 cuadros en varias horas y todos fueron enviados correctamente a recibir correos electrónicos.

     @Override public void onDestroy() { super.onDestroy(); startService(new Intent(this, YourService.class)); } 

    Escriba encima del código en su servicio y su servicio nunca parará incluso el usuario desea destruirlo o quieren matarlo él nunca matará hasta que su app no ​​consiga la desinstalación de su dispositivo

    Puede intentar iniciar su servicio repetidamente, por ejemplo cada 5 seg. De esta manera, cuando su servicio se está ejecutando, se realizará onStartCommand () cada 5 s. He probado este esquema y es muy fiable, pero por desgracia aumenta ligeramente overhead teléfono. Aquí está el código en su actividad donde inicia el servicio.

     Intent iFileObserver = new Intent(StartServicesActivity.this, FileObserverService.class); PendingIntent pendingIntentFileObserver = PendingIntent.getService(StartServicesActivity.this, 0, iFileObserver, 0); AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); Date now = new Date(); //start every 5 seconds alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, now.getTime(), 5*1000, pendingIntentFileObserver); 

    Y aquí está onStartCommand () del servicio.

     //class variable public static boolean isStarted = false; public int onStartCommand(Intent intent, int flags, int startId) { int res = super.onStartCommand(intent, flags, startId); //check if your service is already started if (isStarted){ //yes - do nothing return Service.START_STICKY; } else { //no isStarted = true; } /**** the rest of your code ***/ return Service.START_STICKY; } 

    Por lo que sé, onDestroy() se llamará sólo cuando el servicio se detiene explícitamente (Force Stop). Pero este método no se llamará en caso de que el servicio sea asesinado por OS / pasar la lista de aplicaciones recientes. En esos casos, se llama a otro controlador de eventos llamado onTaskRemoved(Intent) . Esto se debe a un defecto en Android 4.3-4.4 según el enlace aquí . Trate de usar el siguiente código: –

     public void onTaskRemoved(Intent intent){ super.onTaskRemoved(intent); Intent intent=new Intent(this,this.getClass()); startService(intent); } 

    Primero crear servicio en otro proceso, y escribir broadcaster que se ejecuta en la recursividad en los intervalos de tiempo

     protected CountDownTimer rebootService = new CountDownTimer(9000, 9000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { sendBroadcast(reboot); this.start(); Log.d(TAG, "rebootService sending PREVENT AUTOREBOT broadcast"); } }; 

    Después de que el receptor de radiodifusión de registro en el proceso principal también con la recursión del temporizador que se inicia después de la primera difusión del servicio llegó

     protected static class ServiceAutoRebooter extends BroadcastReceiver { private static ServiceAutoRebooter instance = null; private RebootTimer rebootTimer = null; private static ServiceAutoRebooter getInstance() { if (instance == null) { instance = new ServiceAutoRebooter(); } return instance; } public class RebootTimer extends CountDownTimer { private Context _context; private Intent _service; public RebootTimer(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { _context.startService(_service); this.cancel(); Log.d(TAG, "Service AutoRebooted"); } } @Override public void onReceive(Context context, Intent intent) { if (rebootTimer == null) { Log.d(TAG, "rebootTimer == null"); rebootTimer = new RebootTimer(10000, 10000); rebootTimer._context = context; Intent service = new Intent(context, SomeService.class); rebootTimer._service = service; rebootTimer.start(); } else { rebootTimer.cancel(); rebootTimer.start(); Log.d(TAG, "rebootTimer is restarted"); } } } 

    El servicio se reiniciará automáticamente si caduca el tiempo en RebootTimer (proceso principal), lo que significa que no ha llegado la transmisión "PREVENT AUTOREBOT" desde el servicio

    Encontré una solución …. respuesta tardía, pero quería responder …

    Podemos enviar una emisión en la ondestroy del servicio y crear un receptor que reciba la emisión e inicie de nuevo el servicio … cuando sea destruido por cualquier motivo …

    Pls intento siguiente:

     final Messenger mMessenger = new Messenger(new IncomingHandler()); class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { default: super.handleMessage(msg); } } } @Override public void onCreate() { super.onCreate(); makeServiceForeground(); } @Override public IBinder onBind(Intent arg0) { return mMessenger.getBinder(); } private void makeServiceForeground() { IActivityManager am = ActivityManagerNative.getDefault(); try { am.setProcessForeground(onBind(null), android.os.Process.myPid(), true); } catch (RemoteException e) { Log.e("", "cant set to foreground" + e.toString()); } } 

    También necesita agregar en manifest.xml

     <uses-permission android:name="android.permission.SET_PROCESS_LIMIT"/> 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.