Chính xác thì onSaveInstanceState () và onRestoreInstanceState () được gọi khi nào?


102

Hình sau (từ tài liệu chính thức ) mô tả vòng đời nổi tiếng của một hoạt động Android:

nhập mô tả hình ảnh ở đây

Mặt khác, khi hoạt động bị phá hủy bởi hệ thống (ví dụ như do bộ nhớ cần được khôi phục), trạng thái của hoạt động đôi khi được tự động lưu và khôi phục bằng các phương thức onSaveInstanceState()onRestoreInstanceState()như được minh họa trong hình sau (cũng từ tài liệu chính thức ):

nhập mô tả hình ảnh ở đây

Tôi biết rằng onSaveInstanceState()không phải lúc nào gọi là khi một hoạt động sắp bị phá hủy. Ví dụ, nếu nó bị phá hủy vì người dùng đã nhấn nút "quay lại", trạng thái hoạt động sẽ không được giữ nguyên. Nhưng trong các trường hợp khi trạng thái được lưu và khôi phục, và onSaveInstanceState()/ onRestoreInstanceState()được gọi, chúng được gọi chính xác khi nào?

Ví dụ, theo các số liệu trên, onRestoreInstanceState()có thể được gọi trước onStart(), hoặc sau onStart()nhưng trước onResume()hoặc sau onResume(). Tương tự, một số khả năng tồn tại cho onSaveInstanceState(). Vậy chúng được gọi chính xác là khi nào?

Lý tưởng nhất, những gì tôi muốn là xem một sơ đồ kết hợp hiển thị trạng thái vòng đời hoạt động và các phương pháp lưu / khôi phục , nếu tồn tại.


đã có câu trả lời cuối cùng từ tài liệu chính thức của Android, onSaveInstanceState () được gọi giữa onPause () và onStop ().
Rishi

1
@Rishi Bạn có thể vui lòng cung cấp liên kết đến tài liệu đó không?
Luis Mendo


đọc Lưu trạng thái hoạt động của bạn Đoạn văn ở đó
Rishi

cho dù tôi có đúng hay không, vui lòng làm rõ
Rishi

Câu trả lời:


107

Theo tài liệu :

void onRestoreInstanceState (Gói đã lưuInstanceState)

Phương thức này được gọi giữa onStart()onPostCreate(Bundle).

void onSaveInstanceState (Gói outState)

Nếu được gọi, phương thức này sẽ xảy ra sau onStop () cho các ứng dụng nhắm mục tiêu nền tảng bắt đầu bằng Build.VERSION_CODES.P. Đối với các ứng dụng nhắm mục tiêu các phiên bản nền tảng trước đó, phương pháp này sẽ xảy ra trước onStop () và không có gì đảm bảo về việc nó sẽ xảy ra trước hay sau onPause ().


1
Cảm ơn. Bạn có thể vui lòng cung cấp các liên kết đến tài liệu không?
Luis Mendo

Bạn hiểu đấy, tôi cũng không nghĩ rằng có bất kỳ điều gì khác giữa onStart () và onPostCreate (), vì vậy onRestoreInstanceState () được xác định rõ ràng trong chuỗi.
Steve M

Cảm ơn rất nhiều. Điều này làm rõ vấn đề này
Luis Mendo

1
@SteveM "Không có đảm bảo nào về việc nó sẽ xảy ra trước hay sau onPause ()" Điều đó có nghĩa là nếu chúng ta cố gắng truy cập một dạng xem (để lưu một số giá trị, chẳng hạn như một chỉ mục từ một listview), chúng ta có thể gặp phải NullPointerExceptions không?
Tiago

3
Sau đó, điều gì được khuyến nghị, lưu cấu trúc dữ liệu trong onPause và khôi phục nó trong onResume thay vì onSaveInstanceState và onRestoreInstanceState?
Gödel77,

18

Theo doc1doc2

onSaveInstanceState

Trước Honeycomb, các hoạt động không được coi là có thể giết cho đến khi chúng bị tạm dừng, có nghĩa là onSaveInstanceState () được gọi ngay trước onPause (). Tuy nhiên, bắt đầu với Honeycomb, các Hoạt động chỉ được coi là có thể tiêu diệt được sau khi chúng bị dừng, có nghĩa là onSaveInstanceState () bây giờ sẽ được gọi trước onStop () thay vì ngay trước onPause ().

onRestoreInstanceState

Phương thức này được gọi giữa onStart () và onPostCreate (Gói) khi hoạt động đang được khởi tạo lại từ trạng thái đã lưu trước đó


thích cách bạn mô tả kịch bản trên các phiên bản Android khác nhau
Jimit Patel

14

Ngoài các câu trả lời đã được đăng, có một thay đổi nhỏ được giới thiệu trong Android P, đó là:

void onSaveInstanceState (Gói outState)

Nếu gọi là, phương pháp này sẽ xảy ra sau khi onStop() cho các ứng dụng nhắm mục tiêu nền tảng bắt đầu với P . Đối với các ứng dụng nhắm mục tiêu các phiên bản nền tảng cũ hơn, phương pháp này sẽ xảy ra trước onStop()và không có gì đảm bảo về việc nó sẽ xảy ra trước hay sau onPause().

Nguồn: docs

Về lý do tại sao thay đổi này được giới thiệu, đây là câu trả lời:

... để ứng dụng có thể thực hiện các giao dịch phân mảnh một cách an toàn onStop()và sẽ có thể lưu trạng thái liên tục sau này.

Nguồn: docs


Xin chào, bình luận tuyệt vời. Bạn có biết ứng dụng nhắm mục tiêu P nhưng chạy trên api thấp hơn sẽ hoạt động như thế nào không? Giống như ứng dụng nhắm mục tiêu api thấp hơn hay nó sẽ nhất quán trên các api và giữ nguyên hành vi "nhắm mục tiêu api"?
Filipkowicz

@Filipkowicz, Do you know how will behave app that target P but runs on lower api?Miễn là ứng dụng đang được chạy trên ví dụ M, thì phiên bản Android mà thiết bị này có không có các thay đổi, được giới thiệu bằng P, có nghĩa là bất kể bạn đã chỉ định mục tiêu, Pbạn sẽ không thấy khác nhau đối với các thiết bị trước P. Hy vọng điều này trả lời câu hỏi của bạn.
azizbekian

Tôi cảm thấy rất thư giãn hôm nay sau khi đọc câu trả lời này, bởi vì tôi đang tham gia khóa học Android miễn phí trên Udacity và họ vẫn còn phiên bản cũ của các hướng dẫn mà trong bài 5 bài tập 8 nói rằng các phương thức onStop và onDestroy không nên có trong hiển thị textView. Nhưng tôi không biết rằng đó là đối với các phiên bản android cũ hơn và tôi đang chạy ứng dụng của mình trên android pie và nhận được phương thức onStop trong textView của mình. Cảm ơn bạn rất nhiều. Cuối cùng cũng cảm thấy tốt.
Sandhu,

6

Đây là thông tin bổ sung cho onSaveInstanceState (Gói)

từ tài liệu

Đừng nhầm lẫn phương thức này với các lệnh gọi lại vòng đời hoạt động như onPause (), luôn được gọi khi một hoạt động đang được đặt ở chế độ nền hoặc đang trên đường bị hủy, hoặc onStop () được gọi trước khi hủy. Một ví dụ về thời điểm onPause () và onStop () được gọi chứ không phải phương thức này là khi người dùng điều hướng trở lại từ hoạt động B đến hoạt động A: không cần gọi onSaveInstanceState (Gói) trên B vì phiên bản cụ thể đó sẽ không bao giờ được khôi phục , vì vậy hệ thống tránh gọi nó. Một ví dụ khi onPause () được gọi chứ không phải onSaveInstanceState (Gói) là khi hoạt động B được khởi chạy trước hoạt động A: hệ thống có thể tránh gọi onSaveInstanceState (Gói) trên hoạt động A nếu nó không bị giết trong thời gian tồn tại của B kể từ đó trạng thái của giao diện người dùng của A sẽ không thay đổi.

Vì vậy, nó được triển khai mặc định cho ..

Việc triển khai mặc định sẽ chăm sóc hầu hết trạng thái giao diện người dùng cho mỗi phiên bản cho bạn bằng cách gọi onSaveInstanceState () trên mỗi chế độ xem trong cấu trúc phân cấp có id và bằng cách lưu id của chế độ xem hiện được tập trung (tất cả đều được khôi phục bởi triển khai mặc định của onRestoreInstanceState (Gói)). Nếu bạn ghi đè phương pháp này để lưu thông tin bổ sung không được từng chế độ xem riêng lẻ nắm bắt, bạn có thể muốn gọi thông qua triển khai mặc định, nếu không, hãy chuẩn bị để tự lưu tất cả trạng thái của từng chế độ xem.


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

// Lệnh gọi lại này chỉ được gọi khi có một phiên bản đã lưu được lưu trước đó bằng cách sử dụng // onSaveInstanceState (). Chúng tôi khôi phục một số trạng thái trong onCreate () trong khi chúng tôi có thể tùy chọn khôi phục // trạng thái khác tại đây, có thể sử dụng được sau khi onStart () hoàn thành. // Gói SaveInstanceState giống như gói được sử dụng trong 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);
} 

Xin lỗi, làm thế nào để trả lời câu hỏi khi các phương thức lưu / khôi phục được gọi, chính xác là như thế nào?
Luis Mendo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.