2012-06-01 34 views
106

Zajmuję się tworzeniem aplikacji dla Androida przez jakiś czas i śledzę wiele postów dotyczących cyklu życia aktywności i cyklu życia aplikacji.co dokładnie robi metoda Activity.finish()?

Wiem, że Activity.finish() wywołuje metody gdzieś w drodze do Activity.onDestroy(), a także usuwa aktywność ze stosu, i myślę, że w jakiś sposób wskazuje na system operacyjny i garbage collector, że może "wykonać swoją sztuczkę" i zwolnić pamięć, gdy znajdź to dobry czas, robiąc to ...

Przyszedłem do tego posta - Is quitting an application frowned upon? i przeczytałem odpowiedź Marka Murphy'ego.

To mnie trochę zdezorientowało, co właściwie robi metoda finish().

Czy jest szansa, że ​​zadzwonię pod numer finish(), a onDestroy() nie zostanie wywołany?

Odpowiedz

119

Dzwoniąc finish() na działalność, metoda onDestroy() jest wykonywana metoda ta może robić takie rzeczy jak:

  1. Odrzuć wszelkie dialogi aktywność zarządzał.
  2. Zamknij wszystkie kursory, którymi zarządzała aktywność.
  3. zamknąć wszystkie otwarte wyszukiwanie dialogowe

Również onDestroy() nie jest destructor. To tak naprawdę nie niszczy obiektu. Jest to tylko metoda, która jest wywoływana w oparciu o pewien stan. Tak więc twoja instancja jest wciąż żywa i bardzo dobrze * po uruchomieniu i zwrocie superklasy onDestroy().Android utrzymuje procesy na wypadek, gdyby użytkownik chciał ponownie uruchomić aplikację, co przyspiesza rozruch. Proces nie będzie działał, a jeśli pamięć wymaga odzyskania, proces zostanie zabity.

+4

tak metoda finish() tylko wywoływanie połączenia z onDestroy() i to wszystko? –

+0

tak to wywołuje onDestroy(), która zniszczy działanie zgodne z pojęciem działania Cykl życia –

+0

Po zakończeniu() wszystkie zmienne w tym działaniu zostaną zniszczone, prawda? Kiedy ponownie wrócę do tego działania, zostaną one ponownie zadeklarowane lub zainicjowane, prawda? –

12

onDestroy() jest przeznaczony do ostatecznego oczyszczenia - uwolnienia zasobów, które można na własną rękę, zamknięcie otwartych połączeń, czytelników, pisarzy, itp. Jeśli go nie zastąpisz, system zrobi to, co musi.

z drugiej strony, finish() po prostu informuje system, że programista chce, aby aktualny Activity został zakończony. Dlatego też później wywołuje onDestroy().

Coś do uwaga:

to nie jest konieczne, aby tylko wezwanie do finish() powoduje wywołanie onDestroy(). Nie. Jak wiemy, system Android może zabijać działania, jeśli wydaje się, że potrzebne są zasoby potrzebne do uwolnienia.

+1

napisałeś że wykończenie() niech system znać aktywność musi zostać zakończona. więc mówisz "do x = powiedz systemowi, aby zrobił x". sekunda rzecz: od twojej odpowiedzi to brzmi jak jest pewien sposób, który zadzwonię finish(), a system zdecyduje się nie wywoływaćDestroy()? Czy to możliwe? –

+0

Masz pierwszą część w prawo. Wywołanie 'finish()' mówi systemowi, aby ukończyło 'Activity'. częścią "x" w twoim oświadczeniu jest "zakończyć (zniszczyć)" Aktywność ". Druga część jest błędna. Właściwie to przegapiłem słowo. Edytowałem odpowiedź. 'onDestroy()' nie jest wywoływane tylko przez 'finish()', system może również wywoływać to samodzielnie. –

+1

Właśnie przeczytałem twój dodatek do odpowiedzi. na razie przegłosowałem odpowiedź, ponieważ uznałem twoje wyjaśnienie za interesujące, ale chciałbym zobaczyć, czy inni będą mieli coś do powiedzenia na ten temat, zanim określą to jako "odpowiedzi". dzięki na razie :) –

5

Metoda Zakończ() zniszczy bieżącą czynność. Możesz użyć tej metody w przypadkach, gdy nie chcesz, aby ta aktywność była ładowana ponownie, gdy użytkownik naciśnie przycisk Wstecz. Zasadniczo kasuje aktywność z bieżącego stosu.

-5

finish() po prostu wysyła z powrotem do poprzedniej działalności w Android lub może można powiedzieć, że to będzie jeden krok wstecz w aplikacji

2

@ user3282164 Zgodnie z cyklu Activity należy przejść przez onPause() ->onStop() ->onDestroy() po wywołaniu finish().

Diagram nie pokazuje żadnej prostej ścieżki od [Activity Running] do [onDestroy()] spowodowanej przez system.

doc mówi „Należy zauważyć, że metoda ta może nigdy nazwać, w przypadku małej ilości pamięci, gdzie system nie ma wystarczającej ilości pamięci, aby utrzymać proces swoją aktywność na prowadzenie po OnPause() wywoływana jest metoda.

+0

** NIE DOKŁADNIE ** zobacz: http://stackoverflow.com/questions/12655898/finish-and-the-activity-lifecycle/30227647#30227647 – ceph3us

3

Różne odpowiedzi i notatki twierdzą, że finish() może pomijaćPause() i onStop() i bezpośrednio wykonywać onDestroy(). Aby być uczciwym, dokumentacja Androida na ten temat (http://developer.android.com/reference/android/app/Activity.html) stwierdza "Aktywność kończy się lub jest niszczona przez system", co jest dość niejednoznaczne, ale może sugerować, że finish() może przejść do onDestroy().

JavaDoc na finiszu() jest podobnie rozczarowujący (http://developer.android.com/reference/android/app/Activity.html#finish()) i nie zwraca uwagi, jaka metoda (metody) są wywoływane w odpowiedzi na finish().

Więc napisałem tę mini-aplikację, poniżej której rejestruje każdy stan po wejściu. Zawiera przycisk, który wywołuje metodę finish() - dzięki czemu możesz zobaczyć dzienniki, z których metod zostaną uruchomione. Ten eksperyment sugerowałby, że finisz() rzeczywiście wywołuje również wywołanie onPause() i onStop(). Oto dane wyjściowe:

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

} 
42

Moje 2 centy za odpowiedź @K_Anas. Wykonałem prosty test na metodzie finish(). Wystawione ważne metody wywołania zwrotnego w cyklu aktywności

  1. Wywoływanie wykończenie() w onCreate(): onCreate() -> onDestroy()
  2. Wywołanie finish() w onStart(): onCreate() -> onStart() -> onStop() -> onDestroy()
  3. Wywołanie zakończone() w onResume(): onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy()

Co mam na myśli, to to, że odpowiedniki metod wraz z dowolnymi metodami są wywoływane, gdy wykonywana jest metoda finish().

np

onCreate() counter part is onDestroy() 
onStart() counter part is onStop() 
onPause() counter part is onResume() 
+0

co jeśli zadzwonisz do końca w trybie onPause? zadzwoni on onStop> onDestroy? – rmpt

+0

Ten stół jest naprawdę użyteczny i opisowy (musisz przewinąć trochę w dół) https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle – winklerrr

+0

@ winklerrr good one. Tak, to jest przydatne – Prakash

1

Moje badania pokazują, że finish() metoda rzeczywiście stawia pewne operacje niszczenia w kolejce, ale nie jest aktywny natychmiast zniszczone. Planowane jest jednak zniszczenie.

Na przykład, jeśli umieścisz finish() w onActivityResult() zwrotnego, natomiast onResume() ma jeszcze biegać, wtedy pierwszy onResume() zostanie wykonany, a dopiero po tym onStop() i onDestroy() są nazywane.

UWAGA: onDestroy() może nie być w ogóle wywoływany, jak podano na documentation.

0

Wygląda na to, że jedyną poprawną odpowiedzią, jak dotąd, jest romnex: "onDestroy() może nie być w ogóle wywoływany". Chociaż w praktyce prawie we wszystkich przypadkach będzie to miało miejsce, nie ma żadnej gwarancji: documentation przy zakończeniu() tylko obiecuje, że wynik działania jest propagowany z powrotem do osoby dzwoniącej, ale nic więcej. Ponadto, lifecycle documentation wyjaśnia, że ​​aktywność jest dająca się usuwać z systemu operacyjnego, gdy tylko onStop() zakończy działanie (lub nawet wcześniej na starszych urządzeniach), co - choć jest mało prawdopodobne, a zatem rzadko spotykane w prostym teście - może oznaczać, że działanie być zabity podczas lub nawet przed wykonaniem polecenia onDestroy().

Jeśli chcesz się upewnić, że wykonano jakąś pracę podczas wywoływania metody finish(), nie możesz umieścić jej w trybieDestroy(), ale będzie to konieczne w tym samym miejscu, w którym wywołasz metodę finish(), tuż przed nazywając to.

1

Wywołanie zakończenia w onCreate() nie wywoła metody onDestroy() bezpośrednio, jak @prakash. Operacja finish() nie rozpocznie się, dopóki nie zwrócisz kontroli do systemu Android.

Telefoniczny finish() w onCreate(): onCreate() -> onStart() -> onResume(). Jeśli wyjścia użytkownika aplikacja wywoła -> OnPause() -> OnStop() -> onDestroy()

Wywołanie wykończenie() w onStart(): onCreate() -> onStart() -> OnStop() -> onDestroy()

Wywołanie finish() w onResume(): onCreate() -> onStart() -> onResume() -> OnPause() -> OnStop() -> onDestroy()

Aby uzyskać dalsze informacje, spójrz na tę oncreate continuous after finish & about finish()

3

również zauważyć, jeśli zadzwonisz wykończenie() po zamiarem nie można wrócić do poprzedniej pracy za pomocą przycisku „Wstecz”

startActivity(intent); 
finish();