0

Donc, j'ai un service que son onDestory() ressemble à ceci:android - si le service onDestory() n'est pas garanti, où dois-je libérer/supprimer les écouteurs, etc.?

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    stopLocationUpdates(); 
    googleApiClient.disconnect(); 
    Foreground.get(this).removeListener(this); 
    // Here I have some code which sets shared preferences values 
    phoneDataManager.markLastLocation(); 
    toastHandler.post(new Runnable() { 

     @Override 
     public void run() { 
      Toast.makeText(getApplicationContext(), "service onDestroy", Toast.LENGTH_SHORT).show(); 
     } 
    }); 
} 

Comme vous pouvez le voir, je passe beaucoup de choses ici (déconnexion et l'arrêt des mises à jour de l'emplacement, faire quelques changements dans la base de données SQLite, et définir certaines valeurs SharedPreferences

d'après ce que je lis, onDestory n'est pas garanti d'être appelé un scénario que j'ai vu qu'il ne soit pas appelé est -..

l'exécution du service - application> fermeture (suppression de liste des applications) -> J'apporte le service à au premier plan en utilisant service.startForeground(1, notification);, notification montre -> en cliquant sur l'action de notification qui déclenche une BroadcastReceiver:

public class ServiceShutDownReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Intent serviceIntent = new Intent(context.getApplicationContext(), LocationService.class); 
     context.stopService(serviceIntent); 
    } 

} 

Le context.stopService(serviceIntent);devrait appel onDestory mais il ne est pas appelée -> donc tout le code dans onDestory n'a pas été réalisé.

Quelle est la meilleure pratique pour ce problème? Idéalement, je veux avoir un morceau de code garanti pour être appelé lorsque le service est arrêté.

+2

"Je veux avoir un morceau de code qui est garanti d'être appelé lorsque le service est arrêté" - qui n'existe pas. Ce qui est garanti, c'est que 'onDestroy()' sera appelé, votre processus sera terminé (dans ce cas, tous vos écouteurs et autres choses sont déjà partis), ou vous avez planté une exception non gérée. – CommonsWare

+0

l'ai eu. Donc, à propos des préférences partagées et des choses en DB, je pense qu'il serait préférable d'avoir une autre classe dont le travail sera de faire tout cela, et l'appeler de la part de broadcastReceiver. Merci! –

Répondre

1

En général, vous ne devez pas vous préoccuper des situations où onDestroy() n'est pas appelée car cela signifie que le système détruit de force et immédiatement le service (et toutes ses ressources et variables locales associées, conservées en mémoire).

Il est recommandé de toujours mettre ici le code qui libère les gestionnaires persistants comme MediaPlayer, BroadcastReceiver, les mises à jour de localisation GPS, etc. Ceci est une bonne pratique et traitera 90% des situations où le service est gracieusement arrêté. Cependant, si vous souhaitez implémenter des «vérifications de dernière minute» personnalisées, vous avez raison de dire que cette méthode ne peut jamais être appelée par le système et que ce code ne sera jamais exécuté. Votre stratégie de développement devrait suivre ce modèle et ne devrait pas en dépendre puisqu'il n'y a pas d'autre moyen fiable de savoir quand un Service est sur le point d'être détruit. En dernier recours, vous pouvez écouter le rappel Application::onLowMemory(), qui est déclenché lorsque le système manque de mémoire et est proche du démarrage des processus de destruction, mais même cela n'est pas garanti à 100%.

+0

Je vois. Ce que je pense que je ferai, c'est de supprimer les mises à jour de localisation/habdler dans 'onDestroy()' parce que quand le processus sera tué, elles seront quand même parties. Au sujet des préférences partagées de dernière minute et des choses de DB, j'aurai une autre classe faisant cela. Est-ce que ça sonne bien? –

+0

Cela ressemble à suivre les bonnes pratiques. Bonne chance! –