Perché estendere la classe delle applicazioni Android?


168

Una Applicationclasse estesa può dichiarare variabili globali. Ci sono altri motivi?


Questa è solo un'idea dalla parte superiore della mia testa, ma dovresti essere in grado di sovrascrivere onCreate e mostrare una schermata di avvio una sola volta anziché MainActivity, ovvero una schermata introduttiva la prima volta che l'utente apre l'app.
btse

Risposte:


29

A parte, non riesco a pensare a uno scenario reale in cui l'estensione dell'applicazione sia preferibile a un altro approccio o necessaria per realizzare qualcosa. Se si dispone di un oggetto costoso e di uso frequente, è possibile inizializzarlo in IntentService quando si rileva che l'oggetto non è attualmente presente. L'applicazione stessa viene eseguita sul thread dell'interfaccia utente, mentre IntentService viene eseguito sul proprio thread.

Preferisco passare i dati da attività a attività con intenti espliciti o utilizzare SharedPreferences. Esistono anche modi per passare i dati da un frammento all'attività principale usando le interfacce.


39
Esistono molti usi dell'estensione della classe dell'applicazione. Uno molto utile è catturare tutte le eccezioni non rilevate nella tua applicazione. Quindi questo è qualcosa che può essere molto utile
png

3
Come si fa a farlo ?
serj

8
+1 per "prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences". Dovremmo sempre eliminare lo stato globale il più possibile e utilizzare gli strumenti Android standard per la gestione dello stato globale invece di var /
statleton

9
perché? prepararsi per Android a un certo punto eseguendoli in processi diversi o qualsiasi altro componente riutilizzabile da qualsiasi app, mentre ciò è intenzionalmente limitato? il solo passaggio degli oggetti dati invece di serializzarli consente di risparmiare CPU e memoria. non è l'ideale in alcun modo la consegna di pacchi per passaggi all'interno del processo sullo stesso dispositivo. Davvero non vedo il punto di intentservice usare così (basta fare l'altro thread con nuovo). davvero molte delle cose che confondono i programmatori provengono da praticamente tutti gli "helper" aggiunti da Google come se le attività fossero eseguite su computer separati.
Lassi Kinnunen,

127

Introduzione:

inserisci qui la descrizione dell'immagine

  1. Se consideriamo un apkfile nel nostro cellulare, è composto da più blocchi utili come, Activitys,Service altri.
  2. Questi componenti non comunicano tra loro regolarmente e non dimenticano che hanno il loro ciclo di vita. che indicano che possono essere attivi contemporaneamente e inattivi l'altro momento.

Requisiti:

  1. A volte potremmo aver bisogno di uno scenario in cui dobbiamo accedere a una variabile e ai suoi stati nell'intero Applicationindipendentemente Activitydall'utente che sta utilizzando,
  2. Un esempio è che un utente potrebbe dover accedere a una variabile che contiene le informazioni sul proprio personale (ad esempio il nome) a cui è necessario accedere attraverso Application,
  3. Possiamo usare SQLite ma creare Cursore chiuderlo ancora e ancora non è buono per le prestazioni,
  4. Potremmo usare Intents per passare i dati ma è goffo e l'attività stessa potrebbe non esistere in un determinato scenario a seconda della disponibilità della memoria.

Usi della classe di applicazione:

  1. Accesso alle variabili attraverso Application,
  2. Puoi utilizzare il Applicationper avviare determinate cose come l'analisi, ecc. Poiché la classe di applicazione viene avviata prima dell'esecuzione di Activitys o Servicess,
  3. Esiste un metodo ignorato chiamato onConfigurationChanged () che viene attivato quando viene modificata la configurazione dell'applicazione (da orizzontale a verticale e viceversa),
  4. C'è anche un evento chiamato onLowMemory () che viene attivato quando il dispositivo Android ha poca memoria.

Nella sezione Requisiti, perché non utilizzare SharedPreferences?

Nel primo esempio come per il salvataggio di informazioni personali, è possibile utilizzare SharedPreferences. Ma gli esempi che hai fornito nell'ultima parte hanno chiarito i miei dubbi. Grazie!
Saurabh Singh,

63

La classe di applicazione è l'oggetto che ha l'intero ciclo di vita dell'applicazione. È il tuo livello più alto come applicazione. esempi di possibili utilizzi:

  • Puoi aggiungere ciò di cui hai bisogno all'avvio dell'applicazione sovrascrivendo onCreate nella classe Application.

  • memorizzare variabili globali che passano da un'attività all'altra. Come Asynctask.

    eccetera


4
L'uso dell'applicazione come discarica per le variabili globali dell'applicazione è un grande odore di codice. Per farlo, dovresti usare le tue classi personalizzate e più specifiche come singoli o con variabili statiche.
Austin,

5
@Austin perché è un odore?
Relm

1
Sì, perché odore? Come affermato in precedenza, la classe Application è in cima alla gerarchia e posso scommettere i miei soldi per il pranzo, che una classe singleton personalizzata è al di sotto di essa. Quindi, se push arriva a spingere e il tuo telefono ha poca memoria, direi che il singleton personalizzato è il primo a essere ucciso, piuttosto che la classe Application (che essenzialmente è la tua intera app).
Starwave

31

A volte si desidera archiviare dati, ad esempio variabili globali a cui è necessario accedere da più attività, a volte ovunque all'interno dell'applicazione. In questo caso, l'oggetto Applicazione ti aiuterà.

Ad esempio, se si desidera ottenere i dati di autenticazione di base per ogni http richiesta , è possibile implementare i metodi per i dati di autenticazione nell'oggetto applicazione.

Successivamente, è possibile ottenere il nome utente e la password in una qualsiasi delle attività come questa:

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

E infine, ricorda di usare l'oggetto Application come oggetto singleton:

 public class MyApplication extends Application {
    private static MyApplication singleton;

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

Per ulteriori informazioni, fare clic su Classe applicazione


2
spiegami gentilmente questo, perché dobbiamo esplicitamente fare oggetto singleton di una classe Application, per quanto ne so è esso stesso un singleton. Possiamo creare più oggetti applicazione, se possibile, come? e quali sono le conseguenze? Si prega di spiegare.
Syed Raza Mehdi,

No, probabilmente solo una classe di applicazione. developer.android.com/guide/topics/manifest/…
IntelliJ Amiya,

allora perché dobbiamo mantenere esplicitamente l'oggetto singleton di esso? Il sistema operativo non lo sta mantenendo per noi? In realtà ho riscontrato un codice in cui è stato creato un oggetto applicazione nella classe di attività e non viene menzionato in manifest. Penso che sia sbagliato, inoltre sono curioso di sapere perché stiamo realizzando un oggetto singleton statico. Quello che pensi sia l'approccio migliore. Grazie per la risposta.
Syed Raza Mehdi,

1
grazie ho trovato la mia risposta qui su questo link developer.android.com/reference/android/app/Application.html
Syed Raza Mehdi

Dov'è l'oggetto * singleton * in questo
Dr. aNdRO,

8

La classe Application è un singleton a cui puoi accedere da qualsiasi attività o ovunque tu abbia un oggetto Context.

Ottieni anche un po 'di ciclo di vita.

È possibile utilizzare il metodo onCreate dell'applicazione per creare un'istanza di oggetti costosi ma utilizzati di frequente come un supporto di analisi. Quindi è possibile accedere e utilizzare quegli oggetti ovunque.


6
"Hai anche un po 'di ciclo di vita." potresti voler riformularlo.
wtsang02,

2
Voglio dire, ricevi alcune chiamate del ciclo di vita, ma non tante quante con un'attività o un frammento. Ad esempio, non esiste onDestroy () per la classe Application.
Jon F Hancock,

Questa classe viene creata automaticamente?
Konstantin Konopko,

Sì. Fintanto che lo specifichi correttamente in AndroidManifest.xml.
Jon F Hancock,

No, non viene creato automaticamente. Devi crearlo e quindi dichiararlo nel tuo file manifest
Ojonugwa Jude Ochalifu,

7

Migliore utilizzo della classe di applicazione. Esempio: supponiamo che sia necessario riavviare il gestore allarmi all'avvio completato.

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);
    }

Mi chiedo perché dobbiamo fare un riferimento statico all'oggetto applicazione, dove possiamo ottenerlo usando getApplication () e digitarlo nella classe dell'applicazione. Per quanto ho capito questo concetto, la classe di applicazione è creata dal sistema operativo stesso e dovrebbe avere solo un'istanza gestita dal sistema operativo. Si prega di spiegare, grazie.
Syed Raza Mehdi,

Hai ragione. La chiamata a getApplication da qualsiasi componente dell'applicazione nella tua app restituisce la singola istanza derivata dall'applicazione che è la tua app. Questo è gestito internamente dal framework Android. Tutto quello che devi fare è trasmettere l'istanza restituita alla tua classe personalizzata che estende l'applicazione. È inoltre necessario impostare il manifest di conseguenza in modo che la classe corretta venga utilizzata dal framework Android per istanziare l'istanza.
Matt Welke,

5

Non una risposta ma un'osservazione : tieni presente che i dati nell'oggetto esteso dell'applicazione non devono essere collegati a un'istanza di un'attività, poiché è possibile che tu abbia due istanze della stessa attività in esecuzione contemporaneamente (una in il primo piano e uno non visibile) .

Ad esempio, si avvia normalmente l'attività tramite il programma di avvio, quindi "si riduce a icona". Quindi avvii un'altra app (ad esempio Tasker) che avvia un'altra istanza della tua attività, ad esempio per creare un collegamento, perché la tua app supporta android.intent.action.CREATE_SHORTCUT. Se viene quindi creato il collegamento e questa chiamata all'attività di creazione del collegamento ha modificato i dati dell'oggetto applicazione, l'attività in esecuzione in background inizierà a utilizzare l'oggetto applicazione modificato una volta riportato in primo piano.


4

Vedo che a questa domanda manca una risposta. Estendo Applicationperché utilizzo l' implementazione di Bill Pugh Singleton ( vedi riferimento ) e alcuni dei miei singoli hanno bisogno di un contesto. La Applicationclasse si presenta così:

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;
    }
}

E i singoli appaiono così:

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();
    }
}

In questo modo non ho bisogno di avere un contesto ogni volta che utilizzo un singleton e ottengo un'inizializzazione sincronizzata pigra con una quantità minima di codice.

Suggerimento: l'aggiornamento del modello singleton di Android Studio consente di risparmiare molto tempo.


3

Penso che tu possa usare la classe Application per molte cose, ma sono tutte legate alla tua necessità di fare alcune cose PRIMA che qualsiasi attività o servizio venga avviato. Ad esempio, nella mia applicazione utilizzo caratteri personalizzati. Invece di chiamare

Typeface.createFromAsset()

da ogni attività per ottenere riferimenti per i miei caratteri dalla cartella Risorse (questo è un male perché provocherà una perdita di memoria poiché manterrai un riferimento alle risorse ogni volta che chiami quel metodo), lo faccio dal onCreate()metodo nella mia classe Applicazione :

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

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

Ora, ho anche un metodo definito come questo:

public static App getAppInstance() {
    return appInstance;
}

e questo:

public Typeface getQuickSandRegular() {
    return quicksandRegular;
}

Quindi, da qualsiasi parte della mia applicazione, tutto ciò che devo fare è:

App.getAppInstance().getQuickSandRegular()

Un altro uso della classe Application per me è verificare se il dispositivo è connesso a Internet PRIMA delle attività e dei servizi che richiedono una connessione effettivamente avviata e intraprendono le azioni necessarie.


1
Ben detto. Ripartizione molto piacevole.
Oluwatobi Adenekan,

3

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

In molte app, non è necessario lavorare direttamente con una classe di applicazione. Tuttavia, ci sono alcuni usi accettabili di una classe di applicazione personalizzata:

  • Attività specializzate che devono essere eseguite prima della creazione della prima attività
  • Inizializzazione globale che deve essere condivisa tra tutti i componenti (segnalazione di arresti anomali, persistenza)
  • Metodi statici per un facile accesso a dati statici immutabili come un oggetto client di rete condiviso

Non si dovrebbe mai archiviare i dati di istanza mutabili all'interno dell'oggetto Applicazione perché se si presume che i dati rimarranno lì, l'applicazione si arresterà inevitabilmente a un certo punto con una NullPointerException. L'oggetto applicazione non è garantito per rimanere in memoria per sempre, verrà ucciso. Contrariamente alla credenza popolare, l'app non verrà riavviata da zero. Android creerà un nuovo oggetto Applicazione e avvierà l'attività in cui l'utente era prima per dare l'illusione che l'applicazione non fosse mai stata uccisa in primo luogo.


1

È possibile accedere alle variabili a qualsiasi classe senza creare oggetti, se è esteso dall'applicazione. Possono essere chiamati a livello globale e il loro stato viene mantenuto fino a quando l'applicazione non viene uccisa.


1

L'uso dell'applicazione di estensione rende l'applicazione sicura per qualsiasi tipo di operazione desiderata durante il periodo di esecuzione dell'applicazione. Ora può essere qualsiasi tipo di variabile e supponiamo che se si desidera recuperare alcuni dati dal server, è possibile inserire l'applicazione asincrona in modo che venga recuperata ogni volta e continuamente, in modo da ottenere automaticamente i dati aggiornati. Utilizzare questo collegamento per ulteriori conoscenze ....

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


non è un thread, quindi "per qualsiasi tipo di operazione desiderata durante il periodo di esecuzione dell'applicazione". non è vero.
Lassi Kinnunen,

1

Per aggiungere alle altre risposte che affermano che si potrebbero desiderare di memorizzare variabili nell'ambito dell'applicazione, per eventuali thread a esecuzione prolungata o altri oggetti che devono essere associati all'applicazione in cui NON si sta utilizzando un'attività (l'applicazione non è un'attività). come non essere in grado di richiedere un servizio associato .. quindi si preferisce l'associazione all'istanza dell'applicazione. L'unico avvertimento ovvio con questo approccio è che gli oggetti vivono per tutto il tempo in cui l'applicazione è viva, quindi è necessario un controllo più implicito sulla memoria, altrimenti si verificano problemi relativi alla memoria come le perdite.

Qualcos'altro che potresti trovare utile è che nell'ordine delle operazioni, l'applicazione si avvia prima di qualsiasi attività. In questo lasso di tempo, puoi preparare le pulizie necessarie che si verificherebbero prima della tua prima attività se lo desideri.

2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.