173 votes

Que fait exactement la méthode Activity.finish() ?

Je développe des applications Android depuis un certain temps, et j'ai suivi de nombreux posts sur le cycle de vie des activités, et le cycle de vie des applications.

Je sais que Activity.finish() fait appel quelque part à la méthode Activity.onDestroy() Je suppose que cela indique au système d'exploitation et au ramasse-miettes qu'il peut "faire son truc" et libérer la mémoire lorsqu'il le juge opportun....

Je suis arrivé à ce poste - Est-il mal vu de quitter une application ? et lisez la réponse de Mark Murphy.

Cela m'a rendu un peu confus quant à la nature exacte de la finish() est en fait le résultat de cette méthode.

Y a-t-il une chance que j'appelle finish() y onDestroy() ne sera pas appelé ?

9voto

Udit Kapahi Points 146

La méthode Finish() détruit l'activité en cours. Vous pouvez utiliser cette méthode dans les cas où vous ne voulez pas que cette activité se charge encore et encore lorsque l'utilisateur appuie sur le bouton "retour". En fait, elle efface l'activité de la pile actuelle.

6voto

CoderOfTheNight Points 43

Plusieurs réponses et notes affirment que finish() peut ignorer onPause() et onStop() et exécuter directement onDestroy(). Pour être honnête, la documentation Android à ce sujet ( http://developer.Android.com/reference/Android/app/Activity.html ) note "Activity is finishing or being destroyed by the system", ce qui est assez ambigu mais pourrait suggérer que finish() peut passer à onDestroy().

La JavaDoc sur finish() est tout aussi décevante ( [http://developer.Android.com/reference/Android/app/Activity.html#finish()](http://developer.android.com/reference/android/app/Activity.html#finish()) ) et n'indique pas quelle(s) méthode(s) est (sont) appelée(s) en réponse à finish().

J'ai donc écrit cette mini-application ci-dessous qui enregistre chaque état à l'entrée. Elle inclut un bouton qui appelle finish() -- ainsi vous pouvez voir les logs des méthodes qui sont lancées. Cette expérience suggère que finish() en effet appelle également onPause() et onStop(). Voici le résultat que j'obtiens :

2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onCreate
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onStart
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onResume
2170-2170/? D/LIFECYCLE_DEMO﹕ User just clicked button to initiate finish() 
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onPause
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onStop 
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onDestroy

package com.mvvg.apps.lifecycle;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class AndroidLifecycle extends Activity {

    private static final String TAG = "LIFECYCLE_DEMO";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "INSIDE: onCreate");
        setContentView(R.layout.activity_main);
        LinearLayout layout = (LinearLayout) findViewById(R.id.myId);
        Button button = new Button(this);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                Toast.makeText(AndroidLifecycle.this, "Initiating finish()",
                        Toast.LENGTH_SHORT).show();
                Log.d(TAG, "User just clicked button to initiate finish()");
                finish();
            }

        });

        layout.addView(button);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "INSIDE: onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "INSIDE: onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "INSIDE: onDestroy");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "INSIDE: onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "INSIDE: onResume");
    }

}

4voto

anand krish Points 2304

L'appel à finish dans onCreate() n'appellera pas directement onDestroy() comme l'a dit @prakash. Les finish() L'opération ne commencera même pas tant que vous n'aurez pas redonné le contrôle à Android.

L'appel à finish() dans onCreate() : onCreate() -> onStart() -> onResume() . Si l'utilisateur quitte l'application, celle-ci appellera -> onPause() -> onStop() -> onDestroy()

L'appel à finish() dans onStart() : onCreate() -> onStart() -> onStop() -> onDestroy()

L'appel à finish() dans onResume() : onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy()

Pour plus d'informations, consultez le site suivant oncréer en continu après la fin & à propos de finish()

3voto

rommex Points 162

Mon étude montre que finish() place des opérations de destruction dans la file d'attente, mais l'activité n'est pas détruite immédiatement. La destruction est cependant programmée.

Par exemple, si vous placez finish() en onActivityResult() tandis que onResume() n'a pas encore été exécuté, alors le premier onResume() sera exécutée, et ce n'est qu'après cela que onStop() y onDestroy() sont appelés.

NOTE : onDestroy() peut ne pas être appelé du tout, comme indiqué sur le site web de la Commission européenne. [la documentation](https://developer.android.com/reference/android/app/Activity.html#onDestroy()) .

1voto

urps Points 346

Il semble que la seule réponse correcte jusqu'à présent ait été donnée par romnex : "onDestroy() peut ne pas être appelé du tout". Même si en pratique, dans presque tous les cas, il le sera, il n'y a aucune garantie : La fonction la documentation sur finish() promet seulement que le résultat de l'activité est propagé à l'appelant, mais rien de plus. De plus, la fonction documentation sur le cycle de vie précise que l'activité peut être tuée par le système d'exploitation dès que onStop() se termine (ou même avant sur les appareils plus anciens), ce qui, même si c'est peu probable et donc rare à observer dans un simple test, pourrait signifier que l'activité pourrait être tuée pendant ou même avant l'exécution de onDestroy().

Ainsi, si vous voulez vous assurer qu'un travail est effectué lorsque vous appelez finish(), vous ne pouvez pas le placer dans onDestroy(), mais vous devrez le faire au même endroit où vous appelez finish(), juste avant de l'appeler.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X