Saubere Bindung / Entbindung an einen Service in einer Anwendung

Ich habe eine Android-Anwendung, die für einen persistenten Dienst verbindlich ist (einmal mit startService() gestartet).

Der Service ist ein integraler Bestandteil der Anwendung und wird daher in fast jeder Aktivität eingesetzt. Daher möchte ich nur einmal an den Dienst binden (anstelle von Bindung / Entbindung in jeder Aktivität) und die Bindung während der Laufzeit meiner Bewerbung behalten.

  • Android ProgressBar Countdown
  • Wie erstelle ich einen regulären Ausdruck dafür in android?
  • Adb error: mehr als ein gerät - android
  • Rückkehr zum Startbildschirm aus der Aktivität
  • Android LocationClient-Klasse ist veraltet, wird aber in der Dokumentation verwendet
  • Transaktionen halten sich in Puffer (Google Analytics SDK für Android)
  • Ich habe mich von der Anwendung erweitert und binden an den Service in Application # onCreate () . Allerdings habe ich jetzt das Problem, dass ich nicht weiß, wann meine Anwendung existiert, da Application # onTerminate () nie aufgerufen wird, siehe JavaDoc:

    Diese Methode ist für den Einsatz in emulierten Prozessumgebungen vorgesehen. Es wird nie auf eine Android-Android-Gerät aufgerufen werden, wo Prozesse entfernt werden, indem sie einfach töten; Es wird kein Benutzercode (einschließlich dieses Rückrufs) ausgeführt.

    Also, wie kann ich mich von einem Service, der in der Anwendung gebunden ist, reinigen?

  • Wie ändere ich die Farbe des Tabs Indikator Text in Android?
  • Android - Benachrichtigung Manager, mit einer Benachrichtigung ohne Absicht
  • Textansicht mit Langtext drückt andere Ansichten in GridLayout trotz Ellipse = Ende aus
  • Wie bekomme ich das lokalisierte Label der Telefontypen?
  • Wie funktionieren Android-Screen-Koordinaten?
  • Wie migriere man von einer bezahlten Android-Anwendung zu einem Antrag, der für die In-App-Abrechnung bezahlt wurde?
  • 3 Solutions collect form web for “Saubere Bindung / Entbindung an einen Service in einer Anwendung”

    Ich habe dieses Problem gelöst, indem ich die Verweise auf die Servicebindung in der Application zähle. Jede Activity muss acquireBinding() in ihren onCreate() Methoden aufrufen und releaseBinding() in onDestroy() . Wenn der Referenzzähler Null erreicht, wird die Bindung freigegeben.

    Hier ist ein Beispiel:

     class MyApp extends Application { private final AtomicInteger refCount = new AtomicInteger(); private Binding binding; @Override public void onCreate() { // create service binding here } public Binding acquireBinding() { refCount.incrementAndGet(); return binding; } public void releaseBinding() { if (refCount.get() == 0 || refCount.decrementAndGet() == 0) { // release binding } } } // Base Activity for all other Activities abstract class MyBaseActivity extend Activity { protected MyApp app; protected Binding binding; @Override public void onCreate(Bundle savedBundleState) { super.onCreate(savedBundleState); this.app = (MyApp) getApplication(); this.binding = this.app.acquireBinding(); } @Override public void onDestroy() { super.onDestroy(); this.app.releaseBinding(); } } 

    Von Sven's Antwort:

    Ich habe dieses Problem gelöst, indem ich die Verweise auf die Servicebindung in der Anwendung zähle. Jede Aktivität muss acquireBinding () in ihren onCreate () Methoden aufrufen und releaseBinding () in onDestroy () aufrufen. Wenn der Referenzzähler Null erreicht, wird die Bindung freigegeben.

    Ich stimme zu, aber du solltest es nicht in onDestroy machen – das wird oft nicht angerufen.

    Stattdessen schlage ich folgendes vor (basierend auf deinem Codebeispiel) …

     // Base Activity for all other Activities abstract class MyBaseActivity extend Activity { protected MyApp app; protected Binding binding; @Override public void onCreate(Bundle savedBundleState) { super.onCreate(savedBundleState); this.app = (MyApp) getApplication(); this.binding = this.app.acquireBinding(); } @Override protected void onPause() { super.onPause(); // Pre-HC, activity is killable after this. if ((11 > Build.VERSION.SDK_INT) && (isFinishing())) onFinishing(); } @Override protected void onStop() { super.onStop(); if ((10 < Build.VERSION.SDK_INT) && (isFinishing())) onFinishing(); } protected void onFinishing() { // Do all activity clean-up here. this.app.releaseBinding(); } } 

    ABER, mein Gebrauch von isFinishing () ist nur ein Gedanke – ich bin nicht sicher, dass es zuverlässig ist. Vielleicht onPause / onStop bekommst mit isFinishing () false, aber dann wird die Aktivität getötet – und deine ReleaseBinding () wird niemals angerufen.

    Wenn Sie den isFinishing-Check loswerden, denke ich, dass Sie den acquireBinding () – Aufruf von onCreate auf onStart / onResume (abhängig von der Sdk-Version) verschieben müssen, um sicherzustellen, dass Ihre Ref-Zählung nicht durcheinander gebracht wird.

    Wer wusste, dass die Freigabe der App Ihrer App wäre so kompliziert!

    Ist in diesem Fall überhaupt unbindlich notwendig? Die Anwendung wird sowieso getötet. Ich habe versucht, eine Beispielanwendung zu implementieren, die dies ohne ungebunden macht und es scheint richtig zu funktionieren.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.