Pourquoi étendre la classe Application Android?


168

Une Applicationclasse étendue peut déclarer des variables globales. Y a-t-il d'autres raisons?


Ce n'est qu'une idée qui me vient à l'esprit, mais vous devriez être en mesure de remplacer onCreate et d'afficher un écran de démarrage unique plutôt que MainActivity, c'est-à-dire un écran d'introduction la première fois que l'utilisateur ouvre l'application.
btse

Réponses:


29

Offhand, je ne peux pas penser à un scénario réel dans lequel l'extension de l'application est soit préférable à une autre approche, soit nécessaire pour accomplir quelque chose. Si vous disposez d'un objet coûteux et fréquemment utilisé, vous pouvez l'initialiser dans un IntentService lorsque vous détectez que l'objet n'est pas actuellement présent. L'application elle-même s'exécute sur le thread d'interface utilisateur, tandis que IntentService s'exécute sur son propre thread.

Je préfère passer des données d'activité à activité avec des intentions explicites ou utiliser SharedPreferences. Il existe également des moyens de transmettre des données d'un fragment à son activité parente à l'aide d'interfaces.


39
Il existe de nombreuses utilisations de l'extension de la classe d'application. Une très utile est de détecter toutes les exceptions non interceptées dans votre application. Donc, c'est quelque chose qui peut être très pratique
png

3
Comment tu fais ça ?
serj

8
+1 pour "prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences". Nous devrions toujours éliminer l'état global autant que nous le pouvons et utiliser des outils Android standard pour la gestion globale de l'état au lieu de vars / singletons statiques, etc.
Oleksandr Karaberov

9
Pourquoi? se préparer à Android à un moment donné en les exécutant dans différents processus ou autre et chaque composant étant réutilisable par n'importe quelle application, alors que cela est intentionnellement limité? le simple fait de passer les objets de données au lieu de les sérialiser permet d'économiser le processeur et la mémoire. le colisage pour les transferts internes de processus sur le même appareil n'est en aucun cas idéal. Je ne vois vraiment pas l'intérêt d'utiliser intentservice comme ça (il suffit de faire l'autre thread avec new). vraiment beaucoup de choses qui déroutent les codeurs viennent du fait que pratiquement tous les "helpers" ajoutés par Google sont créés comme si les activités se déroulaient sur des ordinateurs séparés.
Lassi Kinnunen

127

Introduction:

entrez la description de l'image ici

  1. Si nous considérons un apkfichier dans notre mobile, il est composé de plusieurs blocs utiles tels que, Activitys, Services et autres.
  2. Ces composants ne communiquent pas régulièrement entre eux et n'oublient pas qu'ils ont leur propre cycle de vie. qui indiquent qu'ils peuvent être actifs à un moment et inactifs à l'autre moment.

Exigences:

  1. Parfois, nous pouvons avoir besoin d'un scénario dans lequel nous devons accéder à une variable et à ses états dans l'ensemble, Applicationquel que soit Activityl'utilisateur utilise,
  2. Par exemple, un utilisateur peut avoir besoin d'accéder à une variable contenant ses informations personnelles (par exemple, son nom) auxquelles il faut accéder via le Application,
  3. Nous pouvons utiliser SQLite mais créer un Cursoret le fermer encore et encore n'est pas bon pour les performances,
  4. Nous pourrions utiliser Intents pour transmettre les données mais c'est maladroit et l'activité elle-même peut ne pas exister dans un certain scénario en fonction de la disponibilité de la mémoire.

Utilisations de la classe d'application:

  1. Accès aux variables à travers le Application,
  2. Vous pouvez utiliser le Applicationpour démarrer certaines choses comme l'analyse, etc. puisque la classe d'application est démarrée avant que Activitys ou Servicess ne soient exécutés,
  3. Il existe une méthode surchargée appelée onConfigurationChanged () qui est déclenchée lorsque la configuration de l'application est modifiée (horizontale à verticale et vice-versa),
  4. Il existe également un événement appelé onLowMemory () qui est déclenché lorsque la mémoire de l'appareil Android est insuffisante.

Dans votre partie Exigence, pourquoi ne pas utiliser SharedPreferences?

Dans le 1er exemple, comme pour enregistrer des informations personnelles, SharedPreferences peut être utilisé. Mais les exemples que vous avez donnés dans la dernière partie ont dissipé mes doutes. Merci!
Saurabh Singh

63

La classe d'application est l'objet qui a le cycle de vie complet de votre application. C'est votre couche la plus élevée en tant qu'application. exemple d'utilisations possibles:

  • Vous pouvez ajouter ce dont vous avez besoin au démarrage de l'application en remplaçant onCreate dans la classe Application.

  • stocker les variables globales qui passent de l'activité à l'activité. Comme Asynctask.

    etc


4
Utiliser Application comme dépotoir pour les variables globales d'application est une grosse odeur de code. Vous devez utiliser vos propres classes personnalisées plus spécifiques en tant que singletons ou avec des variables statiques pour ce faire.
Austin

5
@Austin pourquoi est-ce une odeur?
Relm

1
Ouais, pourquoi sentir? Comme indiqué précédemment, la classe Application est au sommet de la hiérarchie, et je peux parier mon argent de déjeuner, qu'une classe singleton personnalisée est en dessous. Donc, si le push vient à pousser et que votre téléphone manque de mémoire, je dirais que le singleton personnalisé est le premier à être tué, plutôt que la classe Application (qui est essentiellement votre application entière).
Starwave

31

Parfois, vous souhaitez stocker des données, comme des variables globales qui doivent être accessibles à partir de plusieurs activités - parfois partout dans l'application. Dans ce cas, l'objet Application vous aidera.

Par exemple, si vous souhaitez obtenir les données d'authentification de base pour chaque requête http , vous pouvez implémenter les méthodes pour les données d'authentification dans l'objet d'application.

Après cela, vous pouvez obtenir le nom d'utilisateur et le mot de passe dans l'une des activités comme celle-ci:

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

Et enfin, n'oubliez pas d'utiliser l'objet Application comme objet singleton:

 public class MyApplication extends Application {
    private static MyApplication singleton;

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

Pour plus d'informations, cliquez sur Classe d'application


2
veuillez m'expliquer ceci, pourquoi nous devons explicitement créer un objet singleton d'une classe Application, pour autant que je sache, c'est lui-même un singleton. Pouvons-nous créer plusieurs objets d'application, si nous le pouvons, alors comment? et quelles en sont les conséquences? Veuillez expliquer.
Syed Raza Mehdi

Non, probablement une seule classe d'application. developer.android.com/guide/topics/manifest/…
IntelliJ Amiya

alors pourquoi nous avons besoin d'en maintenir explicitement l'objet singleton? OS ne le maintient-il pas pour nous? En fait, j'ai rencontré un code dans lequel il y a un objet d'application créé dans la classe d'activité et il n'est pas mentionné dans le manifeste. Je pense que c'est faux, je suis également curieux de savoir pourquoi nous créons un objet singleton statique. Ce que vous pensez est la meilleure approche. Merci d'avoir répondu.
Syed Raza Mehdi

1
merci j'ai trouvé ma réponse ici sur ce lien developer.android.com/reference/android/app/Application.html
Syed Raza Mehdi

Où est * singleton * objet dans cela
Dr. aNdRO

8

La classe Application est un singleton auquel vous pouvez accéder à partir de n'importe quelle activité ou de tout autre endroit où vous avez un objet Context.

Vous obtenez également un peu de cycle de vie.

Vous pouvez utiliser la méthode onCreate de l'application pour instancier des objets coûteux mais fréquemment utilisés, comme un assistant d'analyse. Ensuite, vous pouvez accéder et utiliser ces objets partout.


6
"Vous obtenez également un peu de cycle de vie." vous voudrez peut-être reformuler cela.
wtsang02

2
Je veux dire que vous recevez des appels de cycle de vie, mais pas autant qu'avec une activité ou un fragment. Par exemple, il n'y a pas de onDestroy () pour la classe Application.
Jon F Hancock

Cette classe est-elle automatiquement créée?
Konstantin Konopko

Oui. Tant que vous le spécifiez correctement dans votre AndroidManifest.xml.
Jon F Hancock

Non, il n'est pas créé automatiquement, vous devez le créer puis le déclarer dans votre fichier manifeste
Ojonugwa Jude Ochalifu

7

Meilleure utilisation de la classe d'application. Exemple: supposons que vous deviez redémarrer votre gestionnaire d'alarmes une fois le démarrage terminé.

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

Je me demande pourquoi nous devons créer une référence statique de l'objet d'application, alors que nous pouvons l'obtenir en utilisant getApplication () et le transposer en classe d'application. Pour autant que j'ai compris ce concept, la classe d'application est créée par le système d'exploitation lui-même et ne devrait avoir qu'une seule instance gérée par le système d'exploitation. Veuillez expliquer, merci.
Syed Raza Mehdi

Vous avez raison. L'appel de getApplication à partir de n'importe quel composant d'application de votre application renvoie l'instance unique dérivée de l'application qui est votre application. Ceci est géré en interne par le framework Android. Tout ce que vous avez à faire est de convertir cette instance renvoyée en votre classe personnalisée qui étend Application. Vous devez également définir votre manifeste en conséquence afin que la classe appropriée soit utilisée par le framework Android pour instancier l'instance.
Matt Welke

5

Pas une réponse mais une observation : gardez à l'esprit que les données de l'objet d'application étendue ne doivent pas être liées à une instance d'une activité, car il est possible que vous ayez deux instances de la même activité en cours d'exécution en même temps (une dans le premier plan et un non visible) .

Par exemple, vous démarrez normalement votre activité via le lanceur, puis vous la «minimisez». Vous démarrez ensuite une autre application (ex. Tasker) qui démarre une autre instance de votre activité, par exemple pour créer un raccourci, car votre application prend en charge android.intent.action.CREATE_SHORTCUT. Si le raccourci est ensuite créé et que cet appel de l'activité créant un raccourci a modifié les données de l'objet d'application, alors l'activité exécutée en arrière-plan commencera à utiliser cet objet d'application modifié une fois qu'il sera ramené au premier plan.


4

Je vois qu'il manque une réponse à cette question. Je prolonge Applicationparce que j'utilise l' implémentation de Bill Pugh Singleton ( voir référence ) et certains de mes singletons ont besoin de contexte. La Applicationclasse ressemble à ceci:

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

Et les singletons ressemblent à ceci:

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

De cette façon, je n'ai pas besoin d'avoir un contexte chaque fois que j'utilise un singleton et d'obtenir une initialisation synchronisée paresseuse avec une quantité minimale de code.

Conseil: la mise à jour du modèle singleton Android Studio permet de gagner beaucoup de temps.


3

Je pense que vous pouvez utiliser la classe Application pour beaucoup de choses, mais elles sont toutes liées à votre besoin de faire certaines choses AVANT que vos activités ou services ne soient démarrés. Par exemple, dans mon application, j'utilise des polices personnalisées. Au lieu d'appeler

Typeface.createFromAsset()

à partir de chaque activité pour obtenir des références pour mes polices à partir du dossier Assets (c'est mauvais car cela entraînera une fuite de mémoire car vous conservez une référence aux actifs chaque fois que vous appelez cette méthode), je le fais à partir de la onCreate()méthode de ma classe Application :

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

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

Maintenant, j'ai aussi une méthode définie comme ceci:

public static App getAppInstance() {
    return appInstance;
}

et ça:

public Typeface getQuickSandRegular() {
    return quicksandRegular;
}

Donc, de n'importe où dans mon application, il ne me reste plus qu'à:

App.getAppInstance().getQuickSandRegular()

Une autre utilisation de la classe Application pour moi est de vérifier si l'appareil est connecté à Internet AVANT que les activités et les services qui nécessitent une connexion ne démarrent et prennent les mesures nécessaires.


1
Bien dit. Très belle panne.
Oluwatobi Adenekan

3

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

Dans de nombreuses applications, il n'est pas nécessaire de travailler directement avec une classe d'application. Cependant, il existe quelques utilisations acceptables d'une classe d'application personnalisée:

  • Tâches spécialisées à exécuter avant la création de votre première activité
  • Initialisation globale qui doit être partagée entre tous les composants (rapport de plantage, persistance)
  • Méthodes statiques pour un accès facile aux données statiques immuables telles qu'un objet client réseau partagé

Vous ne devez jamais stocker de données d'instance modifiables dans l'objet Application, car si vous supposez que vos données y resteront, votre application se bloquera inévitablement à un moment donné avec une exception NullPointerException. L'objet application n'est pas garanti de rester en mémoire pour toujours, il sera tué. Contrairement à la croyance populaire, l'application ne sera pas redémarrée à partir de zéro. Android créera un nouvel objet Application et démarrera l'activité là où l'utilisateur se trouvait auparavant pour donner l'illusion que l'application n'a jamais été tuée en premier lieu.


1

Vous pouvez accéder aux variables de n'importe quelle classe sans créer d'objets, si elle est étendue par Application. Ils peuvent être appelés globalement et leur état est conservé jusqu'à ce que l'application ne soit pas supprimée.


1

L'utilisation de l'extension de l'application garantit simplement à votre application tout type d'opération que vous souhaitez tout au long de la période d'exécution de votre application. Maintenant, il peut s'agir de n'importe quel type de variables et supposons que si vous voulez récupérer des données du serveur, vous pouvez mettre votre asynctask dans l'application afin qu'elle récupère à chaque fois et en continu, afin que vous obteniez automatiquement des données mises à jour. Utilisez ce lien pour plus de connaissances ...

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


ce n'est pas un thread, donc "pour tout type d'opération que vous souhaitez tout au long de la période d'exécution de votre application". ce n'est pas vrai.
Lassi Kinnunen

1

Pour ajouter aux autres réponses indiquant que vous souhaiterez peut-être stocker des variables dans la portée de l'application, pour tous les threads de longue durée ou autres objets qui nécessitent une liaison à votre application où vous n'utilisez PAS d'activité (l'application n'est pas une activité). comme ne pas pouvoir demander un service lié. alors la liaison à l'instance d'application est préférée. Le seul avertissement évident avec cette approche est que les objets vivent aussi longtemps que l'application est vivante, donc un contrôle plus implicite de la mémoire est nécessaire, sinon vous rencontrerez des problèmes liés à la mémoire tels que des fuites.

Une autre chose que vous pouvez trouver utile est que dans l'ordre des opérations, l'application démarre avant toute activité. Dans ce laps de temps, vous pouvez préparer tout entretien ménager nécessaire qui aurait lieu avant votre première activité si vous le souhaitez.

2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.