Apa yang tepatnya dilakukan oleh metode Activity.finish ()?

156

Saya mengembangkan aplikasi android untuk sementara waktu, dan mengikuti banyak posting tentang siklus hidup aktivitas, dan siklus hidup aplikasi.

Saya tahu Activity.finish()panggilan metode di suatu tempat di jalan ke Activity.onDestroy(), dan juga menghapus aktivitas dari tumpukan, dan saya kira itu entah bagaimana menunjuk ke sistem operasi dan pengumpul sampah bahwa ia dapat "melakukan triknya" dan membebaskan memori ketika itu menemukan waktu yang baik melakukan begitu....

Saya datang ke pos ini - Apakah berhenti dari aplikasi disukai? dan baca jawaban Mark Murphy.

Itu membuat saya sedikit bingung tentang apa sebenarnya finish()metode ini.

Apakah ada kemungkinan saya akan menelepon finish()dan onDestroy()tidak akan dipanggil?

Tal Kanel
sumber

Jawaban:

171

Saat memanggil finish()suatu aktivitas, metode onDestroy()ini dijalankan. Metode ini dapat melakukan hal-hal seperti:

  1. Singkirkan semua dialog yang dikelola aktivitas.
  2. Tutup semua kursor yang dikelola aktivitas.
  3. Tutup semua dialog pencarian terbuka

Juga, onDestroy()bukan destruktor. Itu tidak benar-benar menghancurkan objek. Itu hanya metode yang disebut berdasarkan kondisi tertentu. Jadi instance Anda masih hidup dan sangat baik * setelah superclass onDestroy()berjalan dan kembali. Android terus memproses jika pengguna ingin me-restart aplikasi, ini membuat fase startup lebih cepat. Proses tidak akan melakukan apa pun dan jika ingatan perlu direklamasi, proses itu akan dimatikan

K_Anas
sumber
5
jadi metode finish () hanya memicu panggilan ke onDestroy () dan hanya itu?
Tal Kanel
9
Ya, jika Anda kembali ke Activity onCreate () akan dipanggil.
Luis Pena
9
Apakah selesai () juga memanggil onPause () dan onStop ()?
sr09
36
Saya menguji lagi, dan menemukan bahwa onPause (), onStop () dan onDestroy () semuanya akan dipanggil secara berurutan setelah Anda memanggil selesai ().
Sam003
5
@Laurent onPause () dan onStop () tidak selalu dipanggil. Lihat pengamatan saya dalam jawaban di bawah ini
Prakash
77

2 sen saya pada jawaban @K_Anas. Saya melakukan tes sederhana pada metode finish (). Mencantumkan metode panggilan balik penting dalam siklus hidup aktivitas

  1. Memanggil selesai () di onCreate (): onCreate () -> onDestroy ()
  2. Memanggil selesai () di onStart (): onCreate () -> onStart () -> onStop () -> onDestroy ()
  3. Memanggil selesai () di onResume (): onCreate () -> onStart () -> onResume () -> onPause () -> onStop () -> onSest () -> onDestroy ()

Yang ingin saya katakan adalah bahwa rekan-rekan dari metode bersama dengan metode di antaranya dipanggil ketika finish () dieksekusi.

misalnya:

 onCreate() counter part is onDestroy()
 onStart() counter part is onStop()
 onPause() counter part is onResume()
Prakash
sumber
bagaimana jika Anda memanggil selesai di dalam Jeda? itu akan memanggil onStop> onDestroy?
rmpt
Tabel itu sangat berguna dan deskriptif (Anda harus sedikit gulir ke bawah) developer.android.com/reference/android/app/…
winklerrr
Saya sendiri telah memverifikasi bahwa jawaban ini benar.
Sreekanth Karumanaghat
33

Perhatikan juga jika Anda memanggil selesai () setelah niat, Anda tidak dapat kembali ke aktivitas sebelumnya dengan tombol "kembali"

startActivity(intent);
finish();
Dan Wears Prada
sumber
Ini persis info yang saya butuhkan, karena saya memiliki aktivitas yang hanya terhubung ke google drive, kemudian melakukan pengecekan dan bergerak ke aktivitas utama (atau ke aktivitas Pengaturan jika ada kesalahan), sehingga pengguna tidak boleh bisa kembali.
Francesco Marchetti-Stasi
1
@Francesco Marchetti-Stasi Dalam kasus Anda akan lebih baik untuk menimpa onBackPressed () dan tidak memanggil super.onBackPressed () di dalamnya jika pengguna tidak boleh kembali.
Paul
13

onDestroy()dimaksudkan untuk pembersihan akhir - membebaskan sumber daya yang Anda dapat sendiri, menutup koneksi terbuka, pembaca, penulis, dll. Jika Anda tidak menimpanya, sistem melakukan apa yang harus dilakukan.

di sisi lain, finish()biarkan sistem tahu bahwa pemrogram ingin arus Activitydiselesaikan. Dan karenanya, ia memanggil onDestroy()setelah itu.

Sesuatu yang perlu diperhatikan:

tidak perlu hanya panggilan untuk finish()memicu panggilan onDestroy(). Tidak. Seperti yang kita ketahui, sistem android bebas untuk mematikan aktivitas jika merasa ada sumber daya yang dibutuhkan saat ini Activityyang perlu dibebaskan.

Kazekage Gaara
sumber
1
Anda menulis bahwa finish () beri tahu sistem aktivitas harus selesai. jadi itu seperti mengatakan "do x = beri tahu sistem untuk melakukan x". detik hal: dari jawaban Anda sepertinya ada cara saya akan memanggil finish (), dan sistem akan memutuskan untuk tidak memanggil onDestroy ()? apa itu mungkin?
Tal Kanel
Anda mendapatkan bagian pertama yang benar. Memanggil finish()memberitahu sistem untuk menyelesaikan Activity. bagian "x" dalam pernyataan do Anda adalah "untuk menyelesaikan (menghancurkan) Activity". Bagian kedua salah. Sebenarnya, saya melewatkan satu kata di sana. Saya telah mengedit jawabannya. onDestroy()tidak hanya dipicu oleh finish(), sistem dapat memanggilnya sendiri juga.
Kazekage Gaara
1
Saya baru saja membaca tambahan Anda untuk jawabannya. untuk saat ini saya telah memilih-pilih jawaban karena saya menemukan penjelasan Anda menarik, tetapi saya ingin melihat apakah ada yang lain mengatakan sesuatu tentangnya sebelum menandainya sebagai "answerd". terima kasih untuk sekarang :)
Tal Kanel
Jadi setelah selesai (), semua variabel dalam aktivitas ini akan dihancurkan, bukan? Ketika saya kembali ke aktivitas ini sekali lagi, mereka akan dideklarasikan ulang atau diinisialisasi, kan?
Sibbs Gambling
3
Catatan: jika sistem membunuh prosesnya, onDestroy mungkin tidak dipanggil. developer.android.com/reference/android/app/…
Kevin Lee
9

Metode Finish () akan menghancurkan aktivitas saat ini. Anda dapat menggunakan metode ini jika Anda tidak ingin aktivitas ini dimuat lagi dan lagi saat pengguna menekan tombol kembali. Pada dasarnya itu membersihkan aktivitas dari tumpukan .current.

Udit Kapahi
sumber
8

Selain jawaban @rommex di atas, saya juga memperhatikan bahwa finish()antrian penghancuran Aktivitas dan tergantung pada prioritas Kegiatan.

Jika saya memanggil finish()setelah onPause(), saya melihat onStop(), dan onDestroy()segera menelepon.

Jika saya menelepon finish()setelah onStop(), saya tidak melihat onDestroy()sampai 5 menit kemudian.

Dari pengamatan saya, sepertinya selesai di-antri dan ketika saya melihat adb shell dumpsys activity activitiesitu diatur finishing=true, tetapi karena tidak lagi di latar depan, itu tidak diprioritaskan untuk penghancuran.

Singkatnya, onDestroy()tidak pernah dijamin untuk dipanggil, tetapi bahkan dalam kasus itu disebut, itu bisa ditunda.

Brandon Lim
sumber
5

Berbagai jawaban dan catatan mengklaim bahwa finish () dapat melewati onPause () dan onStop () dan langsung menjalankan onDestroy (). Agar adil, dokumentasi Android tentang ini ( http://developer.android.com/reference/android/app/Activity.html ) mencatat "Aktivitas sedang selesai atau dihancurkan oleh sistem" yang cukup ambigu tetapi mungkin menyarankan bahwa finish () dapat melompat ke onDestroy ().

JavaDoc on finish () juga mengecewakan ( http://developer.android.com/reference/android/app/Activity.html#finish () ) dan tidak benar-benar mencatat metode apa yang disebut sebagai respons terhadap penyelesaian. ().

Jadi saya menulis aplikasi mini ini di bawah ini yang mencatat setiap negara bagian saat masuk. Ini termasuk tombol yang memanggil selesai () - sehingga Anda dapat melihat log metode mana yang dipecat. Eksperimen ini menyarankan bahwa finish () memang juga memanggil onPause () dan onStop (). Ini adalah output yang saya dapatkan:

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

}
CoderOfTheNight
sumber
3

@ user3282164 Menurut siklus hidup Aktivitas, ia harus melalui onPause()-> onStop()-> onDestroy()saat meneleponfinish() .

Diagram tidak menunjukkan jalur lurus dari [Activity Running] ke [ onDestroy()] yang disebabkan oleh sistem.

onStop () doc mengatakan " Perhatikan bahwa metode ini mungkin tidak pernah dipanggil, dalam situasi memori rendah di mana sistem tidak memiliki cukup memori untuk menjaga proses aktivitas Anda berjalan setelah metode onPause () dipanggil. "

Meryan
sumber
JANGAN
SAMA
2

Penelitian saya menunjukkan bahwa finish()metode sebenarnya menempatkan beberapa operasi penghancuran dalam antrian, tetapi Kegiatan tidak segera dihancurkan. Penghancuran dijadwalkan.

Misalnya, jika Anda menempatkan finish()di onActivityResult()callback, sementara onResume()belum berjalan, maka pertama onResume()akan dieksekusi, dan hanya setelah itu onStop()dan onDestroy()disebut.

CATATAN: onDestroy()tidak dapat dipanggil sama sekali, seperti yang dinyatakan pada dokumentasi .

rommex
sumber
2

memanggil selesai di onCreate () tidak akan memanggil onDestroy () secara langsung seperti kata @prakash. The finish()operasi bahkan tidak akan dimulai sampai Anda kembali kontrol untuk Android.

Memanggil selesai () di onCreate () : onCreate () -> onStart () -> onResume () . Jika pengguna keluar dari aplikasi akan memanggil -> onPause () -> onStop () -> onDestroy ()

Memanggil selesai () di onStart () : onCreate () -> onStart () -> onStop () -> onDestroy ()

Memanggil selesai () di onResume () : onCreate () -> onStart () -> onResume () -> onPause () -> onStop () -> onSest () -> onDestroy ()

Untuk referensi lebih lanjut, lihat pada oncreate ini terus menerus setelah selesai & sekitar selesai ()

anand krish
sumber
0

Tampaknya satu-satunya jawaban yang benar di sini sejauh ini telah diberikan oleh romnex: "onDestroy () mungkin tidak disebut sama sekali". Meskipun dalam praktiknya, dalam hampir semua kasus itu akan, tidak ada jaminan: Dokumentasi pada selesai () hanya menjanjikan bahwa hasil kegiatan disebarkan kembali ke penelepon, tetapi tidak lebih. Selain itu, dokumentasi siklus hidup mengklarifikasi bahwa aktivitas tersebut dapat dibunuh oleh OS segera setelah onStop () selesai (atau bahkan lebih awal pada perangkat yang lebih tua), yang, meskipun tidak mungkin dan karena itu jarang diamati dalam tes sederhana, mungkin berarti aktivitas tersebut mungkin terbunuh ketika atau bahkan sebelum onDestroy () dieksekusi.

Jadi, jika Anda ingin memastikan beberapa pekerjaan selesai ketika Anda memanggil selesai (), Anda tidak bisa memasukkannya ke dalam onDestroy (), tetapi harus dilakukan di tempat yang sama di mana Anda memanggil selesai (), tepat sebelum benar-benar memanggilnya.

URL
sumber
-4

finish () baru saja mengirim kembali ke aktivitas sebelumnya di android, atau mungkin Anda dapat mengatakan bahwa itu akan mundur satu langkah dalam aplikasi

kapil
sumber