377 Stimmen

Singletons vs. Anwendungskontext in Android?

Daran erinnernd Beitrag, in dem verschiedene Probleme bei der Verwendung von Singletons aufgezählt werden und nachdem ich mehrere Beispiele von Android-Anwendungen gesehen habe, die das Singleton-Muster verwenden, frage ich mich, ob es eine gute Idee ist, Singletons anstelle von einzelnen Instanzen zu verwenden, die über den globalen Anwendungsstatus gemeinsam genutzt werden (Unterklassifizierung von Android.os.Application und Abruf über context.getApplication()).

Welche Vorteile/Nachteile hätten beide Mechanismen?

Um ehrlich zu sein, erwarte ich die gleiche Antwort in diesem Beitrag Singleton-Muster bei Webanwendungen, keine gute Idee! sondern auf Android angewendet. Liege ich richtig? Was ist anders in DalvikVM sonst?

EDIT: Ich würde gerne Meinungen zu verschiedenen Aspekten einholen:

  • Synchronisierung
  • Wiederverwendbarkeit
  • Prüfung

298voto

Matthias Punkte 42368

Ich bin mit der Antwort von Dianne Hackborn ganz und gar nicht einverstanden. Wir entfernen nach und nach alle Singletons aus unserem Projekt zugunsten von leichtgewichtigen, aufgabenspezifischen Objekten, die leicht neu erstellt werden können, wenn man sie tatsächlich braucht.

Singletons sind ein Albtraum für das Testen und führen, wenn sie zu träge initialisiert werden, zu "staatlicher Indeterminismus" mit subtilen Nebeneffekten (die plötzlich auftauchen können, wenn Anrufe nach getInstance() von einem Bereich zum anderen). Die Sichtbarkeit wurde als weiteres Problem erwähnt, und da Singletons "global" (= zufällig) Zugriff auf gemeinsam genutzte Zustände, können subtile Fehler entstehen, wenn sie in nebenläufigen Anwendungen nicht richtig synchronisiert werden.

Ich halte es für ein Anti-Muster, es ist ein schlechter objektorientierter Stil, der im Wesentlichen darauf hinausläuft, einen globalen Zustand zu erhalten.

Um auf Ihre Frage zurückzukommen:

Obwohl der Anwendungskontext selbst als Singleton betrachtet werden kann, wird er vom Framework verwaltet und hat eine gut definierte Lebenszyklus , Umfang und Zugriffspfad. Daher glaube ich, dass, wenn Sie app-globalen Zustand verwalten müssen, sollte es hier gehen, nirgendwo sonst. Für alles andere, überdenken Sie, ob Sie 熟々 ein Singleton-Objekt benötigen, oder ob es auch möglich wäre, Ihre Singleton-Klasse umzuschreiben, um stattdessen kleine, kurzlebige Objekte zu instanziieren, die die jeweilige Aufgabe erfüllen.

234voto

hackbod Punkte 89543

Ich kann Singles sehr empfehlen. Wenn Sie ein Singleton haben, das einen Kontext benötigt, haben:

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

Ich bevorzuge Singletons gegenüber Application, weil es hilft, eine App viel organisierter und modularer zu halten - anstatt einen Ort zu haben, an dem der gesamte globale Zustand der App gepflegt werden muss, kann sich jedes einzelne Teil um sich selbst kümmern. Auch die Tatsache, dass Singletons lazily initialisieren (auf Anfrage) statt führen Sie den Weg der tun alle Initialisierung im Voraus in Application.onCreate() ist gut.

Gegen die Verwendung von Singletons ist an sich nichts einzuwenden. Man muss sie nur richtig verwenden, wenn es sinnvoll ist. Das Android-Framework hat tatsächlich eine Menge von ihnen, um prozessspezifische Caches für geladene Ressourcen und andere Dinge zu verwalten.

Auch für einfache Anwendungen ist Multithreading mit Singletons kein Problem, da alle Standard-Callbacks zur Anwendung auf dem Haupt-Thread des Prozesses abgewickelt werden, so dass kein Multithreading auftritt, es sei denn, Sie führen es explizit durch Threads oder implizit durch die Veröffentlichung eines Inhaltsanbieters oder Dienstes IBinder für andere Prozesse ein.

Überlegen Sie sich einfach, was Sie tun :)

22voto

Somatik Punkte 4626

Von: Entwickler > Referenz - Anwendung

Normalerweise ist es nicht notwendig, Application zu unterklassifizieren. In den meisten Situationen, können statische Singletons die gleiche Funktionalität auf modularere Weise bereitstellen Weise bereitstellen. Wenn Ihr Singleton einen globalen Kontext benötigt (z.B. zur Registrierung von Broadcast-Empfänger), kann die Funktion, die ihn abruft, mit einem Context übergeben werden, der intern Context.getApplicationContext() verwendet, wenn wenn das Singleton zum ersten Mal konstruiert wird.

11voto

JoséMi Punkte 11032

Ich hatte das gleiche Problem: Singleton oder machen eine Unterklasse Android.os.Application?

Zuerst habe ich versucht, mit dem Singleton, aber meine App an einem gewissen Punkt macht einen Aufruf an den Browser

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

und das Problem ist, dass, wenn das Handy nicht genug Speicher hat, die meisten Ihrer Klassen (auch Singletons) bereinigt werden, um etwas Speicher zu bekommen, so dass bei der Rückkehr aus dem Browser zu meiner App, stürzte es jedes Mal.

Lösung: Legen Sie die benötigten Daten in einer Unterklasse der Anwendungsklasse ab.

11voto

sunhang Punkte 333

Die Anwendung ist nicht dasselbe wie das Singleton, und zwar aus folgenden Gründen

  1. Die Methode der Anwendung (z. B. onCreate) wird im UI-Thread aufgerufen;
  2. Die Methode des Singletons kann in jedem Thread aufgerufen werden;
  3. In der Methode "onCreate" der Anwendung können Sie den Handler instanziieren;
  4. Wenn das Singleton in einem Nicht-ui-Thread ausgeführt wird, können Sie nicht Handler instanziieren;
  5. Die Anwendung ist in der Lage, den Lebenszyklus der Aktivitäten in der Anwendung mit der Methode "registerActivityLifecycleCallbacks", aber die Singletons haben nicht die Fähigkeit.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X