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

5voto

adranale Punkte 2750

Berücksichtigen Sie beides gleichzeitig:

  • mit Singleton-Objekten als statische Instanzen innerhalb der Klassen.
  • eine gemeinsame Klasse (Context) zu haben, die die Singleton-Instanzen für alle Singelton-Objekte in Ihrer Anwendung zurückgibt, was den Vorteil hat, dass die Methodennamen in Context aussagekräftig sind, z.B.: context.getLoggedinUser() anstelle von User.getInstance().

Darüber hinaus schlage ich vor, dass Sie Ihren Context so erweitern, dass er nicht nur den Zugriff auf Singleton-Objekte ermöglicht, sondern auch einige Funktionen, auf die global zugegriffen werden muss, wie z. B.: context.logOffUser(), context.readSavedData(), usw. Wahrscheinlich wäre eine Umbenennung des Context in Facade dann sinnvoll.

4voto

Fedor Punkte 43061

Sie sind eigentlich identisch. Es gibt nur einen Unterschied, den ich sehe. Mit der Klasse Application können Sie Ihre Variablen in Application.onCreate() initialisieren und sie in Application.onTerminate() zerstören. Mit Singleton müssen Sie sich auf die VM-Initialisierung und -Zerstörung von Statics verlassen.

4voto

RMcGuigan Punkte 1107

Aus dem Mund des sprichwörtlichen Pferdes...

Bei der Entwicklung Ihrer Anwendung kann es erforderlich sein, Daten, Kontext oder Dienste global über Ihre Anwendung hinweg gemeinsam zu nutzen. Wenn Ihre App beispielsweise über Sitzungsdaten verfügt, wie z. B. über den aktuell angemeldeten Benutzer, werden Sie diese Informationen wahrscheinlich freigeben wollen. In Android besteht das Muster zur Lösung dieses Problems darin, dass Ihre Android.app.Application-Instanz alle globalen Daten besitzt und dann Ihre Application-Instanz als Singleton mit statischen Zugriffsmöglichkeiten auf die verschiedenen Daten und Dienste behandelt.

Wenn Sie eine Android-App schreiben, werden Sie garantiert nur eine Instanz der Klasse Android.app.Application haben, und daher ist es sicher (und wird vom Google Android-Team empfohlen), sie als Singleton zu behandeln. Das heißt, Sie können eine statische getInstance()-Methode zu Ihrer Application-Implementierung hinzufügen. Zum Beispiel so:

public class AndroidApplication extends Application {

    private static AndroidApplication sInstance;

    public static AndroidApplication getInstance(){
        return sInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sInstance = this;
    }
}

2voto

Piovezan Punkte 3120

Meine Aktivität ruft finish() auf (wodurch sie nicht sofort beendet wird, aber irgendwann) und ruft Google Street Viewer auf. Wenn ich es in Eclipse debugge, bricht meine Verbindung zur App ab, wenn Street Viewer aufgerufen wird, was ich als Schließen der (gesamten) Anwendung verstehe, angeblich um Speicher freizugeben (da eine einzelne Aktivität, die beendet wird, dieses Verhalten nicht verursachen sollte). Nichtsdestotrotz bin ich in der Lage, den Zustand in einem Bundle über onSaveInstanceState() zu speichern und ihn in der onCreate()-Methode der nächsten Aktivität im Stapel wiederherzustellen. Wenn ich ein statisches Singleton verwende oder Application subclassing, muss ich damit rechnen, dass die Anwendung geschlossen wird und der Status verloren geht (außer ich speichere ihn in einem Bundle). Meiner Erfahrung nach sind sie also in Bezug auf die Zustandserhaltung gleich. Ich habe festgestellt, dass die Verbindung in Android 4.1.2 und 4.2.2 verloren geht, aber nicht in 4.0.7 oder 3.2.4, was meines Erachtens darauf hindeutet, dass sich der Mechanismus zur Wiederherstellung des Speichers irgendwann geändert hat.

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