Les champs statiques dans les classes d'activité ont-ils la garantie de survivre à un cycle de création / destruction?

StackOverflow https://stackoverflow.com/questions/1636500

Question

Je rencontre fréquemment le problème suivant: je dois conserver l’état entre plusieurs invocations d’une activité (c’est-à-dire passer par plusieurs cycles onCreate () / onDelete ()). Malheureusement, le support d’Android à cet égard est vraiment médiocre.

Pour préserver facilement cet état, j’imaginais que, puisque la classe n’était chargée qu’une seule fois par le chargeur de classes, il était sans danger de stocker des données temporaires partagées entre plusieurs instances d’une activité dans un champ Bundle statique.

Cependant, parfois, lorsque l'instance A crée le paquet statique et y stocke des données, puis est détruite et que l'instance B tente de le lire, le champ statique devient subitement NULL.

Cela ne signifie-t-il pas que la classe a été supprimée et rechargée par le chargeur de classes pendant que l'activité traversait un cycle création / destruction? Sinon, comment un champ statique pourrait-il devenir NULL alors qu'il faisait précédemment référence à un objet?

Était-ce utile?

La solution

La première partie de cette réponse est vraiment ancienne - voir ci-dessous la droite façon de le faire

Vous pouvez utiliser l'objet Application pour stocker des objets persistants d'application. Cette FAQ Android traite également de ce problème.

Quelque chose comme ça:

public class MyApplication extends Application{
    private String thing = null;

    public String getThing(){
        return thing;
    }

    public void setThing( String thing ){
        this.thing = thing;
    }
}

public class MyActivity extends Activity {
    private MyApplication app;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        app = ((MyApplication)getApplication());

        String thing = app.getThing();
    }
}

La droite :

Lorsque cette réponse a été écrite pour la première fois, la documentation relative au cycle de vie de l'activité n'était pas aussi performante qu'aujourd'hui. La lecture de la section sur l'état d'activité du document d'activité nous aide à comprendre comment Android veut que nous sauvions l'état. En principe, votre activité commence dans deux circonstances: (1) en tant que nouvelle activité et (2) en raison d’un changement de configuration ou lorsqu’elle est recréée après avoir été détruite à cause de la pression de la mémoire. Lorsque votre activité commence parce qu'il s'agit d'une nouvelle activité, saveInstanceState a la valeur null. Ce n'est pas nul autrement. Si elle est nulle, alors votre activité doit s'initialiser elle-même. Les fragments sont très similaires à Activités, et j'ai couvert ce concept en détail pour mon = "nofollow noreferrer"> Diapositive diapositives AnDevCon-14 . Vous pouvez également consulter le exemple de code pour ma présentation AnDevCon-14 pour plus d'informations. détails.

Reprendre mon exemple précédent ressemblerait au code ci-dessous. Je change un peu la sémantique - dans cette seconde version, je suppose que la chaîne chose est spécifique à l'activité dans un tâche Android , dans l'exemple précédent, il est ambigu. Si vous souhaitez conserver les mêmes données pour plusieurs tâches Android, vous pouvez toujours utiliser soit l'objet Application, soit un autre singleton.

public class MyActivity extends Activity {
    private static final String THING = "THING";

    private String thing;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState==null) {
            // First time here (since we last backed out at least)
            thing = initializeThing(); // somehow we init it
        } else {
            // Rehydrate this new instance of the Activity
            thing = savedInstanceState.getString(THING);
        }

        String thing = app.getThing();
    }

    protected void onSaveInstanceState(Bundle outState) {
        outState.putString(THING, thing);
    }
}

Autres conseils

L’autre façon, également diabolique, de conserver des données statiques consiste à vous demander de créer une classe singleton. Ce singleton garderait une référence statique sur lui-même.

class EvilSingleton{
    private static EvilSingleton instance;

    //put your data as non static variables here

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

Dans la méthode onCreate () de votre activité, vous pouvez accéder / créer le singleton et toutes les données dont vous pourriez avoir besoin. De cette manière, votre activité ou votre application peut être détruite ou recréée autant de fois que vous le souhaitez et tant que l'espace mémoire de votre processus est préservé, vous devriez y aller.

C’est un hack subversif diabolique, donc aucune promesse ;-)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top