Kapan tepatnya onSaveInstanceState () dan onRestoreInstanceState () dipanggil?

102

Gambar berikut (dari dokumen resmi ) mendeskripsikan siklus hidup aktivitas Android yang terkenal:

masukkan deskripsi gambar di sini

Di sisi lain, ketika aktivitas dimusnahkan oleh sistem (misalnya karena memori perlu diambil kembali), status aktivitas terkadang secara otomatis disimpan dan dipulihkan dengan menggunakan metode onSaveInstanceState()dan onRestoreInstanceState(), seperti yang diilustrasikan oleh gambar berikut (juga dari dokumen resmi ):

masukkan deskripsi gambar di sini

Saya sadar bahwa onSaveInstanceState()ini tidak selalu disebut ketika suatu kegiatan akan segera dihancurkan. Misalnya, jika dimusnahkan karena pengguna telah menekan tombol "kembali", status aktivitas tidak dipertahankan. Namun dalam kasus ketika negara yang diselamatkan dan dipulihkan, dan onSaveInstanceState()/ onRestoreInstanceState()dipanggil, kapan tepatnya yang mereka disebut ?

Misalnya menurut gambar di atas, onRestoreInstanceState()mungkin bisa dipanggil sebelum onStart(), atau sesudah onStart()tapi sebelum onResume(), atau sesudah onResume(). Demikian pula, ada beberapa kemungkinan onSaveInstanceState(). Jadi kapan tepatnya mereka dipanggil?

Idealnya, yang saya inginkan adalah melihat diagram gabungan yang menunjukkan status siklus hidup aktivitas dan metode simpan / pulihkan , jika ada.

Luis Mendo
sumber
mendapat jawaban akhir dari dokumen resmi Android, onSaveInstanceState () dipanggil antara onPause () dan onStop ().
Resi
1
@Rishi Bisakah Anda memberikan tautan ke dokumen itu?
Luis Mendo
baca Menyimpan Paragraf status aktivitas Anda di sana
Resi
apakah saya benar atau tidak, mohon klarifikasi
Resi

Jawaban:

107

Sesuai dokumentasi :

void onRestoreInstanceState (Bundel disimpanInstanceState)

Metode ini disebut antara onStart()dan onPostCreate(Bundle).

void onSaveInstanceState (Bundle outState)

Jika dipanggil, metode ini akan terjadi setelah onStop () untuk aplikasi yang menargetkan platform yang dimulai dengan Build.VERSION_CODES.P. Untuk aplikasi yang menargetkan versi platform sebelumnya, metode ini akan terjadi sebelum onStop () dan tidak ada jaminan apakah ini akan terjadi sebelum atau setelah onPause ().

Steve M.
sumber
1
Terima kasih. Bisakah Anda memberikan tautan ke dokumentasi?
Luis Mendo
Ini dia, juga saya rasa tidak ada hal lain antara onStart () dan onPostCreate (), jadi onRestoreInstanceState () didefinisikan dengan baik dalam rantai.
Steve M
Terima kasih banyak. Ini mengklarifikasi masalah
Luis Mendo
1
@SteveM "Tidak ada jaminan apakah itu akan terjadi sebelum atau sesudah onPause ()" Apakah itu berarti jika kita mencoba mengakses tampilan (untuk mendapatkan beberapa nilai untuk disimpan, seperti indeks dari listview) kita mungkin mengalami NullPointerExceptions?
Tiago
3
Lalu, apa yang disarankan, menyimpan struktur data di onPause dan memulihkannya di onResume, bukan di onSaveInstanceState dan onRestoreInstanceState?
Gödel77
18

Sesuai doc1 dan doc2

onSaveInstanceState

Sebelum Honeycomb, aktivitas tidak dianggap dapat dihentikan hingga setelah dijeda, artinya onSaveInstanceState () dipanggil tepat sebelum onPause (). Namun, dimulai dengan Honeycomb, Aktivitas dianggap dapat dimatikan hanya setelah dihentikan, yang berarti bahwa onSaveInstanceState () sekarang akan dipanggil sebelum onStop (), bukan segera sebelum onPause ().

onRestoreInstanceState

Metode ini dipanggil antara onStart () dan onPostCreate (Bundle) saat aktivitas diinisialisasi ulang dari status tersimpan sebelumnya

Pengembang Android
sumber
menyukai cara Anda mendeskripsikan skenario pada berbagai versi Android
Jimit Patel
14

Selain jawaban yang sudah diposting, ada perubahan halus yang diperkenalkan di Android P, yaitu:

void onSaveInstanceState (Bundle outState)

Jika disebut, metode ini akan terjadi SETELAH onStop() untuk aplikasi yang menargetkan platform dimulai dengan P . Untuk aplikasi yang menargetkan versi platform sebelumnya, metode ini akan terjadi sebelum onStop()dan tidak ada jaminan apakah itu akan terjadi sebelum atau sesudah onPause().

Sumber: docs

Mengenai mengapa perubahan ini diperkenalkan, inilah jawabannya:

... sehingga aplikasi dapat melakukan transaksi fragmen dengan aman onStop()dan nantinya dapat menyimpan status persisten.

Sumber: docs

azizbekian
sumber
Hai, komentar bagus. Apakah Anda tahu bagaimana aplikasi berperilaku yang menargetkan P tetapi berjalan pada api yang lebih rendah? Sama seperti aplikasi yang menargetkan api yang lebih rendah atau akan konsisten di seluruh api dan mempertahankan perilaku "api penargetan"?
Filipkowicz
@Filipkowicz, Do you know how will behave app that target P but runs on lower api?Selama aplikasi dijalankan, katakanlah M, maka versi Android yang dimiliki perangkat ini tidak berisi perubahan, yang diperkenalkan di P, yang berarti bahwa terlepas dari Anda telah menentukan target karena PAnda tidak akan melihatnya berbeda untuk perangkat pra-P. Semoga ini menjawab pertanyaan Anda.
azizbekian
Saya merasa sangat santai hari ini setelah membaca jawaban ini, karena saya melakukan kursus gratis android di Udacity dan mereka masih memiliki versi lama dari tutorial yang menyatakan dalam pelajaran 5 latihan 8 bahwa metode onStop dan onDestroy tidak boleh ada di sana. textView yang ditampilkan. Tapi saya tidak tahu itu untuk versi android yang lebih lama dan saya menjalankan aplikasi saya di android pie dan mendapatkan metode onStop di textView saya. Terima kasih banyak. Akhirnya merasa baik.
Sandhu
6

Ini adalah informasi tambahan untuk onSaveInstanceState (Bundle)

dari dokumen

Jangan keliru membedakan metode ini dengan callback siklus hidup aktivitas seperti onPause (), yang selalu dipanggil saat aktivitas ditempatkan di latar belakang atau dalam perjalanan menuju kehancuran, atau onStop () yang dipanggil sebelum pemusnahan. Salah satu contoh saat onPause () dan onStop () dipanggil dan bukan metode ini adalah saat pengguna menavigasi kembali dari aktivitas B ke aktivitas A: tidak perlu memanggil onSaveInstanceState (Bundle) di B karena instance tersebut tidak akan pernah dipulihkan , sehingga sistem tidak perlu memanggilnya. Contoh saat onPause () dipanggil dan bukan onSaveInstanceState (Bundle) adalah saat aktivitas B diluncurkan di depan aktivitas A: sistem mungkin menghindari pemanggilan onSaveInstanceState (Bundle) pada aktivitas A jika tidak dimatikan selama masa aktif B sejak keadaan antarmuka pengguna A akan tetap utuh.

Jadi ini implementasi default untuk ..

Implementasi default menangani sebagian besar status UI per instance untuk Anda dengan memanggil onSaveInstanceState () pada setiap tampilan dalam hierarki yang memiliki id, dan dengan menyimpan id tampilan yang saat ini difokuskan (semuanya dipulihkan oleh implementasi default onRestoreInstanceState (Bundle)). Jika Anda mengganti metode ini untuk menyimpan informasi tambahan yang tidak ditangkap oleh masing-masing tampilan, Anda mungkin ingin memanggil implementasi default, jika tidak bersiaplah untuk menyimpan sendiri semua status setiap tampilan.

Mahmoud Mzz
sumber
0
String activityState;
@Override 
public void onCreate(Bundle savedInstanceState) {
// call the super class onCreate to complete the creation of activity like 
// the view hierarchy 
super.onCreate(savedInstanceState);

// recovering the instance state 
if (savedInstanceState != null) {
     activityState = savedInstanceState.getString(STATE_KEY);
 } 

   setContentView(R.layout.main_activity);
   mTextView = (TextView) findViewById(R.id.text_view);
} 

// Callback ini dipanggil hanya jika ada instance tersimpan yang sebelumnya disimpan menggunakan // onSaveInstanceState (). Kami memulihkan beberapa status di onCreate () sementara kami secara opsional dapat memulihkan // status lain di sini, mungkin dapat digunakan setelah onStart () selesai. // Bundel saveInstanceState sama dengan yang digunakan di onCreate ().

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) {
 mTextView.setText(savedInstanceState.getString(STATE_KEY));
  } 


// invoked when the activity may be temporarily destroyed, save the instance 
//state here 
//this method will be called before onstop

@Override 
 public void onSaveInstanceState(Bundle outState) {
    outState.putString(STATE_KEY, activityState);

    // call superclass to save any view hierarchy 
    super.onSaveInstanceState(outState);
} 
parvez rafi
sumber
Permisi, bagaimana ini menjawab pertanyaan kapan tepatnya metode simpan / pulihkan dipanggil ?
Luis Mendo