Singletons vs. Anwendungskontext in Android?

Ich erinnere mich an diesen Beitrag Aufzählung mehrere Probleme der Verwendung von Singletons und einige Beispiele von Android-Anwendungen mit Singleton-Muster gesehen, ich frage mich, ob es eine gute Idee, Singletons statt einzelne Instanzen durch globalen Anwendungs-Status (Subklassierung android.os.Application und erhalten es zu verwenden Durch context.getApplication ()).

Welche Vorteile / Nachteile hätten beide Mechanismen?

  • Mit facebook sdk im android studio
  • Identifizieren eines Datentyps einer Spalte in einem SQLite Android Cursor
  • Android Ändern Sie die Hintergrundfarbe eines FrameLayout aus Code
  • Android SDK installieren Problem
  • ViewPagerIndicator-Abhängigkeit mit Gradle und Android Studio
  • So ändern Sie die Action-Textfarbe von ActionBar mit AppCompat
  • Um ehrlich zu sein, erwarte ich die gleiche Antwort in diesem Beitrag Singleton Muster mit Web-Anwendung, Nicht eine gute Idee! Aber auf Android angewendet. Hab ich recht? Was ist anders in DalvikVM anders?

    EDIT: Ich hätte gerne Meinungen zu verschiedenen Aspekten:

    • Synchronisation
    • Wiederverwendbarkeit
    • Testen

  • ExpandableListView Slide Animation auf Gruppe expand / collapse
  • Öffne eine URL mit einem Klick von OK Button in android
  • Mit Dagger 2 in den Dienst zu injizieren
  • Android Manifest Attribut nicht erlaubt hier
  • Android ListView setSelectionFromTop funktioniert nicht
  • Fix 3GP-Datei nach dem Streaming von Android Media Recorder
  • 10 Solutions collect form web for “Singletons vs. Anwendungskontext in Android?”

    Ich bin sehr einverstanden mit Dianne Hackborns Antwort. Wir sind Stück für Stück, um alle Singletons aus unserem Projekt zugunsten von leichten, aufgabengeschützten Objekten zu entfernen, die einfach neu erstellt werden können, wenn man sie tatsächlich braucht.

    Singletons sind ein Alptraum zum Testen und werden, wenn sie faul initialisiert werden, "staatlichen Indeterminismus" mit subtilen Nebenwirkungen einführen (die sich plötzlich beim Anfahren von getInnance () von einem Bereich zum anderen bewegen können). Sichtbarkeit wurde als ein anderes Problem erwähnt, und da Singletons "globalen" (= zufälligen) Zugriff auf den gemeinsamen Status bedeuten, können subtile Bugs auftreten, wenn sie nicht ordnungsgemäß in gleichzeitigen Anwendungen synchronisiert werden.

    Ich halte es für ein Anti-Muster, es ist ein schlechter objektorientierter Stil, der im Wesentlichen den globalen Zustand beibehält.

    Um zu deiner Frage zurückzukehren: Obwohl der App-Kontext als Singleton selbst betrachtet werden kann, ist er gerahmt und hat einen gut definierten Lebenszyklus, Umfang und Zugriffspfad. Daher glaube ich, dass, wenn man App-globalen Zustand zu verwalten braucht, sollte es hier, nirgendwo anders. Für irgendetwas anderes, überdenken Sie, wenn Sie wirklich ein Singleton-Objekt benötigen, oder wenn es auch möglich wäre, Ihre Singleton-Klasse umzuschreiben, um stattdessen kleine, kurzlebige Objekte zu instanziieren, die die Aufgabe ausführen.

    Ich empfehle Singletons sehr. Wenn Sie ein Singleton haben, das einen Kontext braucht, haben Sie:

    MySingleton.getInstance(Context c) { // // ... needing to create ... sInstance = new MySingleton(c.getApplicationContext()); } 

    Ich bevorzuge Singletons über die Anwendung, weil es hilft, eine App viel organischer und modularer zu halten – anstatt einen Platz zu haben, wo all dein globaler Staat über die App gepflegt werden muss, kann jedes einzelne Stück sich selbst versorgen. Auch die Tatsache, dass Singletons faulin initialisieren (auf Anfrage) anstatt Sie hinunter den Weg zu tun, alle Initialisierung up-Front in Application.onCreate () ist gut.

    Es gibt nichts, was mit Singletons ungewollt ist. Benutze sie richtig, wenn es sinnvoll ist. Das Android-Framework hat tatsächlich eine Menge von ihnen, denn es zu pflegen pro-Prozess-Caches von geladenen Ressourcen und andere solche Dinge.

    Auch für einfache Anwendungen Multithreading wird nicht zu einem Thema mit Singletons, denn durch Design werden alle Standard-Callbacks an die App auf dem Haupt-Thread des Prozesses verschickt, so dass Sie nicht Multi-Threading passieren, es sei denn, Sie stellen es explizit durch Threads oder Implizit durch die Veröffentlichung eines Content Providers oder Service IBinder auf andere Prozesse.

    Sei nur nachdenklich darüber, was du tust. 🙂

    Von: http://developer.android.com/reference/android/app/Application.html

    Es besteht normalerweise keine Notwendigkeit, die Unterklassen-Anwendung zu übernehmen. In der meisten Situation können statische Singletons die gleiche Funktionalität in einer modulareren Weise bereitstellen. Wenn Ihr Singleton einen globalen Kontext braucht (zB um Broadcast-Empfänger zu registrieren), kann die Funktion, um es abzurufen, einen Kontext erhalten, der intern den Kontext.getApplicationContext () verwendet, wenn er zuerst das Singleton erstellt.

    Die Anwendung ist nicht die gleiche wie die Singleton. Die Gründe sind:

    1. Die Methode der Anwendung (wie onCreate) wird im ui-Thread aufgerufen;
    2. Singletons Methode kann in jedem Thread aufgerufen werden;
    3. In der Methode "onCreate" der Anwendung können Sie Handler instanziieren;
    4. Wenn das Singleton in keinem Ui-Thread ausgeführt wird, kannst du Handler nicht instanziieren;
    5. Anwendung hat die Fähigkeit, den Lebenszyklus der Aktivitäten in der App zu verwalten.Es hat die Methode "registerActivityLifecycleCallbacks". Aber die Singletons hat nicht die Fähigkeit.

    Ich hatte das gleiche Problem: Singleton oder mache eine Unterklasse android.os.Application?

    Zuerst habe ich mit dem Singleton versucht, aber meine App macht irgendwann einen Anruf an den Browser

     Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")); 

    Und das Problem ist, dass, wenn das Mobilteil nicht genug Speicher hat, werden die meisten Ihrer Klassen (sogar Singletons) gereinigt, um etwas Speicher zu bekommen, wenn Sie vom Browser zu meiner App zurückkehren, stürzte es jedes Mal.

    Lösung: benötigte Daten in einer Unterklasse der Anwendungsklasse.

    Betrachten Sie beide gleichzeitig:

    • Singletonobjekte als statische Instanzen innerhalb der Klassen zu haben.
    • Mit einer gemeinsamen Klasse (Kontext), die die Singleton-Instanzen für alle singelton-Objekte in Ihrer Anwendung zurückgibt, was den Vorteil hat, dass die Methodennamen im Kontext sinnvoll sind, zB: context.getLoggedinUser () anstelle von User.getInstance ().

    Darüber hinaus schlage ich vor, dass du deinen Kontext erweitern musst, um nicht nur den Zugriff auf Singleton-Objekte, sondern auch einige Funktionalitäten aufzurufen, auf die weltweit zugegriffen werden muss, wie zB: context.logOffUser (), context.readSavedData () usw. Wahrscheinlich umbenannt den Kontext Fassade wäre dann sinnvoll.

    Sie sind eigentlich gleich. Es gibt einen Unterschied, den ich sehen kann. Mit der Anwendungsklasse können Sie Ihre Variablen in Application.onCreate () initialisieren und sie in Application.onTerminate () zerstören. Mit Singleton musst du VM Initialisierung und Zerstörung von Statik verlassen.

    Meine Aktivität ruft fertig () (was nicht macht es sofort beenden, aber wird schließlich tun) und ruft Google Street Viewer. Wenn ich es auf Eclipse debugge, bricht meine Verbindung zur App, wenn Street Viewer aufgerufen wird, was ich verstehe, wie die (ganze) Anwendung geschlossen ist, angeblich das Speicher freizugeben (da eine einzelne Aktivität fertig ist, sollte dieses Verhalten nicht verursachen) . Trotzdem kann ich den Status in einem Bundle über onSaveInstanceState () speichern und in der onCreate () – Methode der nächsten Aktivität im Stack wiederherstellen. Entweder mit einem statischen Singleton oder Unterklassen Anwendung Ich Gesicht der Anwendung zu schließen und zu verlieren Zustand (es sei denn, ich speichere es in einem Bundle). Also aus meiner Erfahrung sind sie im Hinblick auf die staatliche Erhaltung gleich. Ich habe bemerkt, dass die Verbindung in Android 4.1.2 und 4.2.2 verloren geht, aber nicht auf 4.0.7 oder 3.2.4, was in meinem Verständnis darauf hindeutet, dass sich der Speicherwiederherstellungsmechanismus irgendwann geändert hat.

    Meine 2 Cent:

    Ich habe bemerkt, dass einige Singleton / statische Felder reseted wurden, als meine Aktivität zerstört wurde. Ich habe das auf einigen Low-End-2.3-Geräten bemerkt.

    Mein Fall war ganz einfach: Ich habe nur eine private eingereicht "init_done" und eine statische Methode "init", die ich von activity.onCreate () aufgerufen habe. Ich bemerke, dass die Methode init sich bei einer Neugestaltung der Aktivität erneut ausführte.

    Während ich meine Bestätigung nicht beweisen kann, kann es sein, wenn das Singleton / die Klasse erstellt / verwendet wurde. Wenn die Aktivität zerstört / recycelt wird, scheint es, dass alle Klasse, die nur diese Aktivität verweisen, auch recycelt werden.

    Ich habe meine Instanz von Singleton zu einer Unterklasse der Anwendung bewegt. Ich greife ihnen aus der Anwendungsinstanz zu. Und seitdem habe ich das Problem nicht mehr bemerkt.

    Ich hoffe das kann jemandem helfen.

    Vom Mund des sprichwörtlichen Pferdes …

    Bei der Entwicklung Ihrer App kann es notwendig sein, Daten, Kontext oder Dienste global über Ihre App zu teilen. Wenn zum Beispiel Ihre App Sitzungsdaten wie den aktuell angemeldeten Benutzer hat, werden Sie diese Informationen wahrscheinlich aussetzen. In Android ist das Muster für die Lösung dieses Problems, um Ihre android.app.Application Instanz besitzen alle globalen Daten, und dann behandeln Sie Ihre Anwendung Instanz als Singleton mit statischen Accessoren, um die verschiedenen Daten und Dienste.

    Beim Schreiben einer Android-App sind Sie garantiert nur eine Instanz der android.app.Application-Klasse, und so ist es sicher (und von Google Android-Team empfohlen), um es als Singleton zu behandeln. Das heißt, Sie können sicher eine statische Methode getInstance () zu Ihrer Anwendungsimplementierung hinzufügen. Wie so …

     public class AndroidApplication extends Application{ private static AndroidApplication sInstance; public static AndroidApplication getInstance(){ return sInstance; } @Override public static void onCreate(){ super.onCreate() sInstance = this; } } 
    Das Android ist ein Google Android Fan-Website, Alles über Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.