Comment éviter que le service lié ne soit détruit pendant l'évolution de l'activité (ex: orientation)

J'ai un service lié. Une activité l'engage. Il onStop() méthode onStop() Service on Activity.

Le problème est que, si le temps d'exécution change (par exemple, changement d'orientation) arrive à l'Activité, l'Activité est recréée. Donc, la méthode onStop() est appelée à partir de l'activité, et l'activité désactive le service dans cette méthode, ce qui entraîne la destruction du service (et le redémarrage).

  • Handler ou timer android
  • Quand ACTION_OUTSIDE serait-il déclenché?
  • Emulateur Android - Problème de création de comptes utilisateur
  • SQLITE - supprimer des lignes avec une jointure interne?
  • Comment enregistrer un appel dans Android? C'est possible?
  • Google Firebase - comment supprimer les rapports Crash?
  • Je souhaite que le service ne soit pas détruit pendant les changements d'exécution tout en gardant l'arrêt du service lorsque l'activité est invisible. Vous pourriez dire qu'essayez startService() mais cela rend le service à ne pas arrêter lorsque Activity est invisible. Si j'ajoute onStop onStop() d' onStop() d' onStop() d' onStop() , alors le résultat est identique à bindService() et unbindService() .

    PostDelaying unbindService() dans onStop() de onStop() peut résoudre ce problème en partie, mais le temps de retard sera arbitraire, ce qui empêche l'activité d'obtenir un GC pendant un certain temps. Je souhaite une solution plus claire.

    Je ne veux pas de solutions comme android:configChanges="orientation" puisqu'il y a d'autres changements d'exécution, et c'est un moyen découplé de traiter les changements d'exécution.

    En bref, je veux que le Service agisse comme un Fragment qui s'appelle setRetainInstance(true) . Cependant, les fragments n'ont pas quelque chose comme bindService() . Que devrais-je faire?

    3 Solutions collect form web for “Comment éviter que le service lié ne soit détruit pendant l'évolution de l'activité (ex: orientation)”

    Cependant, les fragments n'ont pas quelque chose comme bindService ().

    Mais ils peuvent utiliser bindService() partir du contexte de l' Application :

     public class BshFragment extends Fragment implements OnClickListener, ServiceConnection { private IScript service=null; private Button btn=null; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View result=inflater.inflate(R.layout.main, container, false); btn=(Button)result.findViewById(R.id.eval); btn.setOnClickListener(this); btn.setEnabled(false); setRetainInstance(true); return(result); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getActivity().getApplicationContext() .bindService(new Intent(getActivity(), BshService.class), this, Context.BIND_AUTO_CREATE); } @Override public void onDestroy() { getActivity().getApplicationContext().unbindService(this); disconnect(); super.onDestroy(); } @Override public void onClick(View view) { EditText script=(EditText)getView().findViewById(R.id.script); String src=script.getText().toString(); service.executeScript(src); } @Override public void onServiceConnected(ComponentName className, IBinder binder) { service=(IScript)binder; btn.setEnabled(true); } @Override public void onServiceDisconnected(ComponentName className) { disconnect(); } private void disconnect() { service=null; btn.setEnabled(false); } } 

    (Comme on l'a vu dans cet exemple de projet , couvert dans ce livre )

    En utilisant le contexte de l' Application , nous sommes en mesure d'utiliser le même Context pour la liaison et la déconnexion. En conservant le fragment, nous pouvons éviter de débrancher et de relier un changement de configuration.

    Personnellement, j'essaie simplement d'éviter le schéma de liaison. Je suis un fan d'interfaces à couplage libre, et je préfère utiliser les services via le motif de commande et startService() .

    Appelez startService dans onCreate, puis onStop

     @Override protected void onStop() { super.onStop(); if (!isChangingConfigurations ()) { // call stopService } } 

    Une autre façon de conserver un service unique pendant les changements d'exécution pourrait être de définir dans la classe de service une méthode comme keepAlive :

     public void keepAlive(boolean value) { if (value) startService(new Intent(getApplicationContext(), getClass())); else stopSelf(); } @Override public void onRebind(Intent intent) { keepAlive(false); } @Override public boolean onUnbind(Intent intent) { return true; } 

    Dans onRebind() l'état du service à contrainte unique est réinitialisé.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.