Warum die Android-Anwendungsklasse erweitern?


168

Eine erweiterte ApplicationKlasse kann globale Variablen deklarieren. Gibt es noch andere Gründe?


Dies ist nur eine Idee aus meinem Kopf, aber Sie sollten in der Lage sein, onCreate zu überschreiben und einen einmaligen Startbildschirm anstelle der MainActivity anzuzeigen, dh einen Intro-Bildschirm, wenn der Benutzer die App zum ersten Mal öffnet.
Btse

Antworten:


29

Auf Anhieb kann ich mir kein reales Szenario vorstellen, in dem die Erweiterung der Anwendung entweder einem anderen Ansatz vorzuziehen ist oder notwendig ist, um etwas zu erreichen. Wenn Sie ein teures, häufig verwendetes Objekt haben, können Sie es in einem IntentService initialisieren, wenn Sie feststellen, dass das Objekt derzeit nicht vorhanden ist. Die Anwendung selbst wird auf dem UI-Thread ausgeführt, während IntentService auf einem eigenen Thread ausgeführt wird.

Ich bevorzuge es, Daten mit expliziten Absichten von Aktivität zu Aktivität zu übergeben oder SharedPreferences zu verwenden. Es gibt auch Möglichkeiten, Daten von einem Fragment über Schnittstellen an die übergeordnete Aktivität zu übergeben.


39
Es gibt viele Verwendungsmöglichkeiten für die Erweiterung der Anwendungsklasse. Eine sehr nützliche Methode besteht darin, alle nicht erfassten Ausnahmen in Ihrer Anwendung abzufangen. SO ist dies etwas, das sehr praktisch sein kann
png

3
Wie machst du das ?
Serj

8
+1 für "prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences". Wir sollten den globalen Status immer so weit wie möglich eliminieren und Standard-Android-Tools für die globale
Statusverwaltung

9
Warum? sich darauf vorzubereiten, dass Android sie irgendwann in verschiedenen Prozessen ausführt oder was auch immer und jede Komponente von jeder App wiederverwendbar ist, während dies absichtlich begrenzt ist? Nur die Datenobjekte zu übergeben, anstatt sie zu serialisieren, spart CPU und Speicher. Paketversand für Übergaben innerhalb des Prozesses auf demselben Gerät ist in keiner Weise ideal. Ich sehe den Sinn der Intentservice-Nutzung wirklich nicht so (mache einfach den anderen Thread mit new). Wirklich viele Dinge, die Codierer verwirren, stammen von so ziemlich allen von Google hinzugefügten "Helfern", als ob die Aktivitäten auf separaten Computern ausgeführt würden.
Lassi Kinnunen

127

Einführung:

Geben Sie hier die Bildbeschreibung ein

  1. Wenn wir eine apkDatei in unserem Handy betrachten, besteht sie aus mehreren nützlichen Blöcken wie z. B. Activitys, Services und anderen.
  2. Diese Komponenten kommunizieren nicht regelmäßig miteinander und vergessen nicht, dass sie einen eigenen Lebenszyklus haben. die darauf hinweisen, dass sie zu einem Zeitpunkt aktiv und im anderen Moment inaktiv sein können.

Bedarf:

  1. Manchmal benötigen wir ein Szenario, in dem wir auf eine Variable und ihre Zustände über den gesamten ApplicationZeitraum zugreifen müssen, unabhängig davon, welchen ActivityBenutzer der Benutzer verwendet.
  2. Ein Beispiel ist, dass ein Benutzer möglicherweise auf eine Variable zugreifen muss, die seine Personalinformationen enthält (z. B. Name), auf die über die Application,
  3. Wir können SQLite verwenden, aber das Erstellen Cursorund Schließen von SQLite ist nicht gut für die Leistung.
  4. Wir könnten Intents verwenden, um die Daten zu übergeben, aber es ist ungeschickt und die Aktivität selbst ist in einem bestimmten Szenario je nach Speicherverfügbarkeit möglicherweise nicht vorhanden.

Verwendung der Anwendungsklasse:

  1. Zugriff auf Variablen in der Application,
  2. Sie können das verwenden Application, um bestimmte Dinge wie Analysen usw. zu starten, da die Anwendungsklasse gestartet wird, bevor Activitys oder Servicess ausgeführt werden.
  3. Es gibt eine überschriebene Methode namens onConfigurationChanged (), die ausgelöst wird, wenn die Anwendungskonfiguration geändert wird (horizontal zu vertikal und umgekehrt).
  4. Es gibt auch ein Ereignis namens onLowMemory (), das ausgelöst wird, wenn auf dem Android-Gerät wenig Speicherplatz vorhanden ist.

Verwenden Sie in Ihrem Anforderungsteil SharedPreferences.

Im ersten Beispiel wie zum Speichern persönlicher Informationen können SharedPreferences verwendet werden. Aber die Beispiele, die Sie im letzten Teil gegeben haben, haben meine Zweifel ausgeräumt. Vielen Dank!
Saurabh Singh

63

Anwendungsklasse ist das Objekt, das den gesamten Lebenszyklus Ihrer Anwendung aufweist. Es ist Ihre höchste Ebene als Anwendung. Beispiel mögliche Verwendungen:

  • Sie können beim Starten der Anwendung hinzufügen, was Sie benötigen, indem Sie onCreate in der Application-Klasse überschreiben.

  • Speichern Sie globale Variablen, die von Aktivität zu Aktivität springen. Wie Asynctask.

    etc


4
Die Verwendung von Application als Abladeplatz für anwendungsglobale Variablen ist ein großer Codegeruch. Sie sollten Ihre eigenen benutzerdefinierten, spezifischeren Klassen als Singletons oder mit statischen Variablen verwenden, um dies zu erreichen.
Austin

5
@Austin warum ist es ein Geruch?
Relm

1
Ja, warum riechen? Wie bereits erwähnt, steht die Anwendungsklasse ganz oben in der Hierarchie, und ich kann mein Geld für das Mittagessen darauf setzen, dass sich eine benutzerdefinierte Singleton-Klasse darunter befindet. Wenn es also zu einem Push kommt und Ihr Telefon nur noch wenig Arbeitsspeicher hat, würde ich sagen, dass der benutzerdefinierte Singleton der erste ist, der getötet wird, und nicht die Anwendungsklasse (die im Wesentlichen Ihre gesamte App ist).
Starwave

31

Manchmal möchten Sie Daten speichern, z. B. globale Variablen, auf die über mehrere Aktivitäten zugegriffen werden muss - manchmal überall in der Anwendung. In diesem Fall hilft Ihnen das Anwendungsobjekt.

Wenn Sie beispielsweise die grundlegenden Authentifizierungsdaten für jede http- Anforderung abrufen möchten , können Sie die Methoden für Authentifizierungsdaten im Anwendungsobjekt implementieren.

Danach können Sie den Benutzernamen und das Passwort für eine der folgenden Aktivitäten erhalten:

MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();

Denken Sie schließlich daran, das Anwendungsobjekt als Singleton-Objekt zu verwenden:

 public class MyApplication extends Application {
    private static MyApplication singleton;

    public MyApplication getInstance(){
        return singleton;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
    }
}

Für weitere Informationen klicken Sie bitte auf Anwendungsklasse


2
Erklären Sie mir bitte, warum wir explizit ein Singleton-Objekt einer Application-Klasse erstellen müssen, soweit ich weiß, dass es sich selbst um ein Singleton handelt. Können wir mehrere Anwendungsobjekte erstellen, wenn wir können, wie dann? und was sind die Konsequenzen? Bitte erklären Sie.
Syed Raza Mehdi

Nein, wahrscheinlich nur eine Anwendungsklasse. developer.android.com/guide/topics/manifest/…
IntelliJ Amiya

Warum müssen wir dann das Singleton-Objekt explizit pflegen? Wartet das Betriebssystem es nicht für uns? Tatsächlich bin ich auf einen Code gestoßen, in dem ein Anwendungsobjekt in der Aktivitätsklasse erstellt wurde und das im Manifest nicht erwähnt wird. Ich denke, das ist falsch, auch ich bin neugierig, warum wir statische Singleton-Objekte machen. Was Sie denken, ist der beste Ansatz. Danke für Ihre Antwort.
Syed Raza Mehdi

1
danke Ich habe meine Antwort hier auf diesem Link gefunden. developer.android.com/reference/android/app/Application.html
Syed Raza Mehdi

Wo ist * singleton * Objekt darin
Dr. aNdRO

8

Die Anwendungsklasse ist ein Singleton, auf den Sie von jeder Aktivität oder von jedem anderen Ort aus zugreifen können, an dem Sie ein Kontextobjekt haben.

Sie erhalten auch ein wenig Lebenszyklus.

Sie können die onCreate-Methode der Anwendung verwenden, um teure, aber häufig verwendete Objekte wie einen Analyse-Helfer zu instanziieren. Dann können Sie überall auf diese Objekte zugreifen und sie verwenden.


6
"Sie bekommen auch ein bisschen Lebenszyklus." Vielleicht möchten Sie das umformulieren.
wtsang02

2
Ich meine, Sie erhalten einige Lebenszyklusaufrufe, aber nicht so viele wie bei einer Aktivität oder einem Fragment. Beispielsweise gibt es kein onDestroy () für die Application-Klasse.
Jon F Hancock

Wird diese Klasse automatisch erstellt?
Konstantin Konopko

Ja. Solange Sie es in Ihrer AndroidManifest.xml korrekt angeben.
Jon F Hancock

Nein, es wird nicht automatisch erstellt. Sie müssen es erstellen und dann in Ihrer Manifestdatei deklarieren
Ojonugwa Jude Ochalifu

7

Beste Verwendung der Anwendungsklasse. Beispiel: Angenommen, Sie müssen Ihren Alarmmanager nach Abschluss des Startvorgangs neu starten.

public class BaseJuiceApplication extends Application implements BootListener {

    public static BaseJuiceApplication instance = null;

    public static Context getInstance() {
        if (null == instance) {
            instance = new BaseJuiceApplication();
        }
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();


    }

    @Override
    public void onBootCompleted(Context context, Intent intent) {
        new PushService().scheduleService(getInstance());
        //startToNotify(context);
    }

Ich frage mich, warum wir eine statische Referenz des Anwendungsobjekts erstellen müssen, wo wir es mit getApplication () abrufen und in die Anwendungsklasse typisieren können. Soweit ich dieses Konzept verstanden habe, wird die Anwendungsklasse vom Betriebssystem selbst erstellt und sollte nur eine Instanz haben, die vom Betriebssystem verwaltet wird. Bitte erklären Sie, danke.
Syed Raza Mehdi

Du hast Recht. Wenn Sie getApplication von einer beliebigen Anwendungskomponente in Ihrer App aus aufrufen, wird die einzelne von der Anwendung abgeleitete Instanz zurückgegeben, die Ihre App ist. Dies wird intern vom Android-Framework erledigt. Sie müssen lediglich die zurückgegebene Instanz in Ihre benutzerdefinierte Klasse umwandeln, die Application erweitert. Sie müssen Ihr Manifest auch entsprechend festlegen, damit das Android-Framework die richtige Klasse zum Instanziieren der Instanz verwendet.
Matt Welke

5

Keine Antwort, sondern eine Beobachtung : Beachten Sie , dass die Daten im erweiterten Anwendungsobjekt nicht an eine Instanz einer Aktivität gebunden sein sollten, da möglicherweise zwei Instanzen derselben Aktivität gleichzeitig ausgeführt werden (eine in) der Vordergrund und einer, der nicht sichtbar ist) .

Zum Beispiel starten Sie Ihre Aktivität normal über den Launcher und "minimieren" sie dann. Anschließend starten Sie eine andere App (z. B. Tasker), die eine andere Instanz Ihrer Aktivität startet, beispielsweise um eine Verknüpfung zu erstellen, da Ihre App android.intent.action.CREATE_SHORTCUT unterstützt. Wenn die Verknüpfung dann erstellt wird und dieser Verknüpfungserstellungsaufruf der Aktivität die Daten des Anwendungsobjekts ändert, verwendet die im Hintergrund ausgeführte Aktivität dieses geänderte Anwendungsobjekt, sobald es wieder in den Vordergrund gestellt wird.


4

Ich sehe, dass dieser Frage eine Antwort fehlt. Ich erweitere, Applicationweil ich die Implementierung von Bill Pugh Singleton verwende ( siehe Referenz ) und einige meiner Singletons Kontext benötigen. Die ApplicationKlasse sieht so aus:

public class MyApplication extends Application {

    private static final String TAG = MyApplication.class.getSimpleName();

    private static MyApplication sInstance;

    @Contract(pure = true)
    @Nullable
    public static Context getAppContext() {
        return sInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate() called");
        sInstance = this;
    }
}

Und die Singletons sehen so aus:

public class DataManager {

    private static final String TAG = DataManager.class.getSimpleName();

    @Contract(pure = true)
    public static DataManager getInstance() {
        return InstanceHolder.INSTANCE;
    }

    private DataManager() {
        doStuffRequiringContext(MyApplication.getAppContext());
    }

    private static final class InstanceHolder {
        @SuppressLint("StaticFieldLeak")
        private static final DataManager INSTANCE = new DataManager();
    }
}

Auf diese Weise muss ich nicht jedes Mal einen Kontext haben, wenn ich einen Singleton verwende, und eine verzögerte synchronisierte Initialisierung mit minimaler Codemenge erhalten.

Tipp: Das Aktualisieren der Android Studio-Singleton-Vorlage spart viel Zeit.


3

Ich denke, Sie können die Anwendungsklasse für viele Dinge verwenden, aber sie hängen alle von Ihrer Notwendigkeit ab, einige Dinge zu tun, bevor eine Ihrer Aktivitäten oder Dienste gestartet wird. In meiner Anwendung verwende ich beispielsweise benutzerdefinierte Schriftarten. Anstatt anzurufen

Typeface.createFromAsset()

Aus jeder Aktivität, um Referenzen für meine Schriftarten aus dem Ordner "Assets" abzurufen (dies ist schlecht, da dies zu einem Speicherverlust führt, da Sie bei jedem Aufruf dieser Methode einen Verweis auf Assets behalten), mache ich dies aus der onCreate()Methode in meiner Anwendungsklasse ::

private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
    super.onCreate();

    appInstance = this;
    quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
                       "fonts/Quicksand-Regular.otf");
   ...
   }

Jetzt habe ich auch eine Methode wie diese definiert:

public static App getAppInstance() {
    return appInstance;
}

und das:

public Typeface getQuickSandRegular() {
    return quicksandRegular;
}

Von überall in meiner Bewerbung muss ich also nur Folgendes tun:

App.getAppInstance().getQuickSandRegular()

Eine andere Verwendung für die Anwendungsklasse besteht für mich darin, zu überprüfen, ob das Gerät mit dem Internet verbunden ist, BEVOR Aktivitäten und Dienste, für die eine Verbindung erforderlich ist, tatsächlich gestartet werden, und die erforderlichen Maßnahmen zu ergreifen.


1
Gut gesagt. Sehr schöne Panne.
Oluwatobi Adenekan

3

Quelle: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class

In vielen Apps muss nicht direkt mit einer Anwendungsklasse gearbeitet werden. Es gibt jedoch einige akzeptable Verwendungen einer benutzerdefinierten Anwendungsklasse:

  • Spezialisierte Aufgaben, die vor der Erstellung Ihrer ersten Aktivität ausgeführt werden müssen
  • Globale Initialisierung, die von allen Komponenten gemeinsam genutzt werden muss (Absturzberichterstattung, Persistenz)
  • Statische Methoden für den einfachen Zugriff auf statische unveränderliche Daten, z. B. ein freigegebenes Netzwerkclientobjekt

Sie sollten niemals veränderbare Instanzdaten im Anwendungsobjekt speichern, da Ihre Anwendung zwangsläufig irgendwann mit einer NullPointerException abstürzt, wenn Sie davon ausgehen, dass Ihre Daten dort verbleiben. Es ist nicht garantiert, dass das Anwendungsobjekt für immer im Speicher bleibt, es wird getötet. Entgegen der landläufigen Meinung wird die App nicht von Grund auf neu gestartet. Android erstellt ein neues Anwendungsobjekt und startet die Aktivität, bei der der Benutzer zuvor war, um die Illusion zu vermitteln, dass die Anwendung überhaupt nicht getötet wurde.


1

Sie können auf Variablen für jede Klasse zugreifen, ohne Objekte zu erstellen, sofern diese durch die Anwendung erweitert wurden. Sie können global aufgerufen werden und ihr Status bleibt erhalten, bis die Anwendung nicht beendet wird.


1

Durch die Verwendung der erweiterten Anwendung wird Ihre Anwendung nur für jede Art von Vorgang sichergestellt, die Sie während der gesamten Laufzeit Ihrer Anwendung ausführen möchten. Jetzt können es beliebige Variablen sein. Wenn Sie Daten vom Server abrufen möchten, können Sie Ihre Asynctask in die Anwendung einfügen, damit sie jedes Mal und kontinuierlich abgerufen wird, sodass Sie automatisch aktualisierte Daten erhalten. Verwenden Sie diesen Link für mehr wissen ....

http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android


Es ist kein Thread, also "für jede Art von Operation, die Sie während der gesamten Laufzeit Ihrer Anwendung ausführen möchten". ist nicht wahr.
Lassi Kinnunen

1

Hinzufügen zu den anderen Antworten, die besagen, dass Sie möglicherweise Variablen im Anwendungsbereich speichern möchten, für alle lang laufenden Threads oder anderen Objekte, die an Ihre Anwendung gebunden werden müssen, wenn Sie KEINE Aktivität verwenden (Anwendung ist keine Aktivität). B. nicht in der Lage zu sein, einen gebundenen Dienst anzufordern. Dann wird die Bindung an die Anwendungsinstanz bevorzugt. Die einzige offensichtliche Warnung bei diesem Ansatz ist, dass die Objekte so lange leben, wie die Anwendung aktiv ist. Daher ist eine implizitere Kontrolle über den Speicher erforderlich, da sonst speicherbezogene Probleme wie Lecks auftreten können.

Etwas anderes, das Sie möglicherweise nützlich finden, ist, dass die Anwendung in der Reihenfolge der Vorgänge zuerst gestartet wird, bevor Aktivitäten ausgeführt werden. In diesem Zeitraum können Sie auf Wunsch alle erforderlichen Reinigungsarbeiten vorbereiten, die vor Ihrer ersten Aktivität durchgeführt werden.

2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.