Nguyên tắc cơ bản về Android 02.2: Vòng đời và trạng thái hoạt động

1. Chào mừng

Giới thiệu

Trong lớp học lập trình này, bạn sẽ tìm hiểu thêm về vòng đời hoạt động (activity lifecycle). Vòng đời là tập hợp trạng thái của một hoạt động trong suốt thời gian hoạt động, từ khi hoạt động được tạo đến khi bị huỷ và hệ thống lấy lại tài nguyên. Khi người dùng di chuyển giữa các hoạt động trong ứng dụng (cũng như vào và ra khỏi ứng dụng), các hoạt động sẽ chuyển đổi giữa nhiều trạng thái trong vòng đời của chúng.

Sơ đồ về Vòng đời của ứng dụng

Mỗi giai đoạn trong vòng đời của một hoạt động có một phương thức gọi lại tương ứng: onCreate(), onStart(), onPause(), v.v. Khi một hoạt động thay đổi trạng thái, phương thức gọi lại được liên kết sẽ được gọi. Bạn đã thấy một trong các phương thức sau: onCreate(). Bằng cơ chế ghi đè phương thức gọi lại bất kỳ trong vòng đời trong các lớp Activity, bạn có thể thay đổi hành vi mặc định của hoạt động để phản hồi thao tác của người dùng hoặc hệ thống.

Trạng thái hoạt động cũng có thể thay đổi theo các thay đổi về cấu hình thiết bị, chẳng hạn như khi người dùng xoay thiết bị từ dọc sang ngang. Khi những thay đổi về cấu hình như vậy diễn ra, hoạt động sẽ bị huỷ và được tạo lại ở trạng thái mặc định. Đồng thời, người dùng có thể mất thông tin đã nhập vào hoạt động. Để tránh gây nhầm lẫn cho người dùng, quan trọng là bạn phải phát triển ứng dụng để ngăn chặn tình trạng mất dữ liệu ngoài mong muốn. Trong phần cuối của lớp học lập trình này, bạn sẽ thử nghiệm các thay đổi về cấu hình và tìm hiểu cách duy trì trạng thái của hoạt động để phản hồi các thay đổi về cấu hình thiết bị cũng như các sự kiện khác trong vòng đời hoạt động.

Trong lớp học lập trình này, bạn sẽ thêm các câu lệnh ghi nhật ký vào ứng dụng TwoActivities rồi quan sát các thay đổi trong vòng đời hoạt động khi bạn sử dụng ứng dụng. Sau đó, bạn bắt đầu làm việc với những thay đổi này và tìm hiểu cách xử lý hoạt động đầu vào của người dùng trong các điều kiện này.

Kiến thức bạn cần có

Bạn phải làm được những việc sau:

  • Tạo và chạy dự án ứng dụng trong Android Studio.
  • Thêm câu lệnh nhật ký vào ứng dụng và xem các nhật ký đó trong ngăn Logcat.
  • Hiểu và xử lý ActivityIntent cũng như thoải mái tương tác với các yếu tố này.

Kiến thức bạn sẽ học được

  • Cách hoạt động của vòng đời Activity.
  • Khi một Activity bắt đầu, tạm dừng, dừng và bị huỷ.
  • Giới thiệu về phương thức gọi lại trong vòng đời liên kết với các thay đổi về Activity.
  • Ảnh hưởng của những thao tác (chẳng hạn như thay đổi về cấu hình) có thể dẫn đến các sự kiện trong vòng đời của Activity.
  • Cách giữ lại trạng thái Activity trong các sự kiện vòng đời.

Bạn sẽ thực hiện

  • Thêm đoạn mã vào ứng dụng TwoActivities trong lớp học lập trình trước đó để triển khai các phương thức gọi lại trong vòng đời của Activity nhằm đưa cả các câu lệnh ghi nhật ký vào.
  • Quan sát trạng thái thay đổi khi ứng dụng chạy và khi bạn tương tác với từng Activity trong ứng dụng.
  • Sửa đổi ứng dụng để giữ lại trạng thái thực thể của Activity được tạo lại đột ngột nhằm phản hồi hành vi của người dùng hoặc thay đổi cấu hình trên thiết bị.

2. Tổng quan về ứng dụng

Trong lớp học lập trình này, bạn sẽ tiếp tục thực hành trên ứng dụng TwoActivities. Ứng dụng này có giao diện và hoạt động gần giống như trong lớp học lập trình trước. Ứng dụng này có hai cách triển khai Activity và cho phép người dùng gửi giữa các cách triển khai. Các thay đổi bạn thực hiện đối với ứng dụng trong lớp học lập trình này sẽ không ảnh hưởng đến hành vi có thể quan sát được của người dùng.

3. Nhiệm vụ 1: Thêm phương thức gọi lại trong vòng đời vào TwoActivities

Trong nhiệm vụ này, bạn sẽ triển khai tất cả phương thức gọi lại trong vòng đời của Activity để in thông điệp lên logcat khi các phương thức đó được gọi. Các thông điệp nhật ký này sẽ cho bạn biết khi nào vòng đời của Activity thay đổi trạng thái và ảnh hưởng của những thay đổi đó đối với ứng dụng của bạn khi ứng dụng chạy.

1.1 (Không bắt buộc) Sao chép dự án TwoActivities

Đối với các nhiệm vụ trong lớp học lập trình này, bạn sẽ sửa đổi dự án TwoActivities hiện có mà bạn đã xây dựng trong lớp học lập trình gần đây nhất. Nếu bạn muốn giữ nguyên dự án TwoActivities trước, hãy làm theo các bước trong Phụ lục: Tiện ích để tạo bản sao của dự án.

1.2 Triển khai phương thức gọi lại cho MainActivity

  1. Mở dự án TwoActivities trong Android Studio rồi mở MainActivity trong ngăn Project (Dự án) > Android.
  2. Trong phương thức onCreate(), hãy thêm các câu lệnh nhật ký sau:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
  1. Thêm một cơ chế ghi đè cho phương thức gọi lại onStart(), kèm theo một câu lệnh cho nhật ký của sự kiện đó:
@Override
public void onStart(){
    super.onStart();
    Log.d(LOG_TAG, "onStart");
}

Để sử dụng phím tắt, hãy chọn Code > Override Method (Mã > Phương thức ghi đè) trong Android Studio. Một hộp thoại sẽ xuất hiện cùng tất cả phương thức mà bạn có thể dùng để ghi đè trong lớp dữ liệu. Thao tác chọn một hoặc nhiều phương thức gọi lại trong danh sách sẽ chèn một mẫu hoàn chỉnh cho các phương thức đó, bao gồm cả phương thức gọi bắt buộc đến lớp cấp cao (superclass).

  1. Sử dụng phương thức onStart() làm một mẫu để triển khai các phương thức gọi lại vòng đời onPause(), onRestart(), onResume(), onStop()onDestroy().

Tất cả phương thức gọi lại đều có cùng chữ ký (ngoại trừ tên). Nếu bạn Copy (Sao chép) rồi Paste (Dán) onStart() để tạo các phương thức gọi lại khác, đừng quên cập nhật nội dung để gọi phương thức phù hợp trong lớp cấp cao cũng như để ghi nhật ký đúng phương thức.

  1. Chạy ứng dụng.
  2. Nhấp vào thẻ Logcat ở cuối Android Studio để hiện ngăn Logcat. Bạn sẽ thấy 3 thông điệp nhật ký cho thấy 3 trạng thái vòng đời mà Activity đã chuyển đổi khi bắt đầu:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume

1.3 Triển khai phương thức gọi lại trong vòng đời trong SecondActivity

Lúc này, bạn đã triển khai các phương thức gọi lại trong vòng đời cho MainActivity, hãy thực hiện tương tự cho SecondActivity.

  1. Mở SecondActivity.
  2. Ở trên cùng của lớp, hãy thêm một hằng số cho biến LOG_TAG:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
  1. Thêm các phương thức gọi lại trong vòng đời và câu lệnh nhật ký vào Activity thứ hai. (Bạn có thể Copy (Sao chép) rồi Paste (Dán) các phương thức gọi lại trên MainActivity.)
  2. Thêm câu lệnh nhật ký vào phương thức returnReply() ngay trước phương thức finish():
Log.d(LOG_TAG, "End SecondActivity");

1.4 Quan sát nhật ký khi ứng dụng chạy

  1. Chạy ứng dụng.
  2. Nhấp vào thẻ Logcat ở cuối Android Studio để hiện ngăn Logcat.
  3. Nhập Activity vào hộp tìm kiếm. Logcat Android có thể rất dài và lộn xộn. Do biến LOG_TAG trong mỗi lớp chứa từ MainActivity hoặc SecondActivity, nên từ khoá này chỉ cho phép bạn lọc nhật ký theo những chủ đề bạn quan tâm.

Nhật ký cho thấy trạng thái vòng đời

Thử nghiệm sử dụng ứng dụng của bạn và lưu ý rằng các sự kiện trong vòng đời xảy ra để phản hồi nhiều thao tác. Cụ thể, hãy thử những thao tác sau:

  • Sử dụng ứng dụng như bình thường (gửi tin nhắn, trả lời bằng tin nhắn khác).
  • Sử dụng nút Quay lại để quay lại từ Activity thứ hai về Activity chính.
  • Sử dụng Mũi tên lên trong thanh ứng dụng để quay lại từ Activity thứ hai về Activity chính.
  • Xoay thiết bị trên cả Activity chính và thứ hai tại nhiều thời điểm trong ứng dụng rồi quan sát xem điều gì xảy ra trong nhật ký và trên màn hình.
  • Nhấn vào nút tổng quan (nút hình vuông ở bên phải Màn hình chính) rồi đóng ứng dụng (nhấn vào X).
  • Quay lại màn hình chính rồi khởi động lại ứng dụng.

LƯU Ý: Nếu đang chạy ứng dụng trong trình mô phỏng thì bạn có thể mô phỏng thao tác xoay bằng Control+F11 hoặc Control+Function+F11.

Đoạn mã giải pháp cho nhiệm vụ 1

Các đoạn mã sau đây là giải pháp cho nhiệm vụ đầu tiên.

MainActivity

Các đoạn mã sau đây là đoạn mã đã thêm trong MainActivity chứ không phải toàn bộ lớp.

Phương thức onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Log the start of the onCreate() method.
        Log.d(LOG_TAG, "-------");
        Log.d(LOG_TAG, "onCreate");

        // Initialize all the view variables.
        mMessageEditText = findViewById(R.id.editText_main);
        mReplyHeadTextView = findViewById(R.id.text_header_reply);
        mReplyTextView = findViewById(R.id.text_message_reply);
}

Các phương thức khác trong vòng đời:

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

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

@Override
protected void onRestart() {
        super.onRestart();
        Log.d(LOG_TAG, "onRestart");
}

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

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

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

SecondActivity

Các đoạn mã sau đây là mã đã thêm trong SecondActivity chứ không phải toàn bộ lớp.

Ở đầu lớp SecondActivity:

private static final String LOG_TAG = SecondActivity.class.getSimpleName();

Phương thức returnReply() :

public void returnReply(View view) {
        String reply = mReply.getText().toString();
        Intent replyIntent = new Intent();
        replyIntent.putExtra(EXTRA_REPLY, reply);
        setResult(RESULT_OK, replyIntent);
        Log.d(LOG_TAG, "End SecondActivity");
        finish();
}

Các phương thức khác trong vòng đời:

Tương tự như trên đối với MainActivity.

4. Nhiệm vụ 2: Lưu và khôi phục trạng thái của thực thể Activity

Tuỳ thuộc vào tài nguyên hệ thống và hành vi của người dùng, mỗi Activity trong ứng dụng của bạn có thể bị huỷ và tạo lại thường xuyên hơn nhiều so với bạn nghĩ.

Có thể bạn đã nhận thấy hành vi này trong phần cuối khi xoay thiết bị hoặc trình mô phỏng. Xoay thiết bị là một ví dụ về việc thay đổi cấu hình thiết bị. Mặc dù chế độ xoay là biến phổ biến nhất, nhưng tất cả thay đổi về cấu hình dẫn đến việc Activity hiện tại đều bị huỷ và tạo lại như mới. Nếu bạn không tính đến hành vi này trong mã nguồn của mình, thì khi tình huống thay đổi cấu hình xảy ra, bố cục Activity có thể quay về giao diện mặc định và các giá trị ban đầu. Đồng thời, người dùng của bạn có thể bị mất thông tin vị trí, dữ liệu hoặc trạng thái tiến trình của họ trong ứng dụng của bạn.

Trạng thái của mỗi Activity được lưu trữ dưới dạng một tập hợp cặp giá trị/khoá trong đối tượng Bundle được gọi là trạng thái thực thể Activity. Hệ thống sẽ lưu thông tin trạng thái mặc định vào trạng thái thực thể Bundle ngay trước khi Activity dừng rồi chuyển Bundle đó đến thực thể Activity mới để khôi phục.

Để tránh mất dữ liệu khi Activity đột ngột bị huỷ và tạo lại, bạn cần triển khai phương thức onSaveInstanceState(). Hệ thống sẽ gọi phương thức này trên Activity của bạn (từ onPause() đến onStop()) khi có khả năng Activity có thể bị huỷ và tạo lại.

Dữ liệu bạn lưu ở trạng thái thực thể chỉ dành riêng cho thực thể này của Activity trong phiên hoạt động hiện tại của ứng dụng. Khi bạn dừng và khởi động lại một phiên ứng dụng mới, trạng thái thực thể Activity sẽ bị mất và Activity chuyển về giao diện mặc định. Nếu bạn cần lưu dữ liệu người dùng giữa các phiên ứng dụng, hãy sử dụng lựa chọn ưu tiên được chia sẻ hoặc một cơ sở dữ liệu. Bạn sẽ tìm hiểu về cả hai phương pháp này trong một lớp học lập trình sau này.

2.1 Lưu trạng thái của thực thể Activity bằng onSaveInstanceState()

Bạn có thể nhận thấy thao tác xoay thiết bị hoàn toàn không ảnh hưởng đến trạng thái của Activity thứ hai. Lý do là bố cục và trạng thái Activity thứ hai được tạo từ bố cục và Intent đã kích hoạt bố cục đó. Ngay cả khi Activity được tạo lại, Intent vẫn ở đó và dữ liệu trong Intent đó vẫn được sử dụng mỗi khi phương thức onCreate() trong Activity thứ hai được gọi.

Ngoài ra, bạn có thể nhận thấy trong mỗi Activity, mọi văn bản bạn nhập vào các thành phần tin nhắn hoặc câu trả lời EditText đều được giữ lại ngay cả khi xoay thiết bị. Điều này là do thông tin trạng thái của một số phần tử View trong bố cục được lưu tự động qua các thay đổi về cấu hình và giá trị hiện tại của EditText thuộc một trong những trường hợp đó.

Vì vậy, trạng thái Activity duy nhất mà bạn quan tâm là các phần tử TextView cho tiêu đề trả lời và văn bản trả lời trong Activity chính. Theo mặc định, cả hai phần tử TextView đều không xuất hiện; chúng chỉ xuất hiện khi bạn gửi tin nhắn lại cho Activity chính qua Activity thứ hai.

Trong nhiệm vụ này, bạn thêm đoạn mã để duy trì trạng thái thực thể của 2 phần tử TextView này bằng cách sử dụng onSaveInstanceState().

  1. Mở MainActivity.
  2. Thêm phương thức triển khai skeleton này của onSaveInstanceState() vào Activity hoặc sử dụng Code > Override Methods (Mã > Phương thức ghi đè) để chèn phần ghi đè skeleton.
@Override
public void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState);
}
  1. Kiểm tra xem tiêu đề hiện tại có xuất hiện hay không. Nếu có, hãy đặt trạng thái hiển thị đó thành trạng thái Bundle bằng phương thức putBoolean() và khoá "reply_visible".
    if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
        outState.putBoolean("reply_visible", true);
    }

Hãy nhớ rằng tiêu đề và văn bản trả lời được đánh dấu là không xuất hiện cho đến khi có câu trả lời của Activity thứ hai. Nếu tiêu đề xuất hiện thì tức là có dữ liệu trả lời cần được lưu. Xin lưu ý rằng chúng ta chỉ quan tâm đến trạng thái hiển thị đó. Văn bản thực tế của tiêu đề không cần được lưu vì văn bản đó không bao giờ thay đổi.

  1. Cũng trong quy trình kiểm tra đó, hãy thêm văn bản trả lời vào Bundle.
outState.putString("reply_text",mReplyTextView.getText().toString());

Nếu tiêu đề xuất hiện thì bạn có thể giả định rằng chính tin nhắn trả lời cũng xuất hiện. Bạn không cần kiểm tra hoặc lưu trạng thái hiển thị hiện tại của tin nhắn trả lời. Chỉ văn bản thực tế của tin nhắn mới chuyển sang trạng thái Bundle bằng khoá "reply_text".

Bạn chỉ lưu trạng thái của các phần tử View có thể thay đổi sau khi tạo Activity. Bạn có thể tạo lại các phần tử View khác trong ứng dụng (EditText, Button) qua bố cục mặc định vào bất cứ lúc nào.

Xin lưu ý rằng hệ thống sẽ lưu trạng thái của một số phần tử View, chẳng hạn như nội dung của EditText.

2.2 Khôi phục trạng thái của thực thể Activity trong onCreate()

Sau khi lưu trạng thái của thực thể Activity, bạn cũng phải khôi phục trạng thái này khi tạo lại Activity. Bạn có thể thực hiện việc này trong onCreate() hoặc bằng cách triển khai phương thức gọi lại onRestoreInstanceState(), được gọi sau onStart() sau khi tạo Activity.

Trong mọi trường hợp, nơi tốt nhất để khôi phục trạng thái Activity là trong onCreate(), nhằm đảm bảo rằng giao diện người dùng (bao gồm cả trạng thái) xuất hiện sớm nhất có thể. Đôi khi, bạn có thể thực hiện việc này trong onRestoreInstanceState() sau khi mọi thao tác khởi chạy đã hoàn tất, hoặc cho phép các lớp con quyết định xem có sử dụng cách triển khai mặc định của bạn hay không.

  1. Trong phương thức onCreate(), sau khi các biến View được khởi chạy bằng findViewById(), hãy thêm một quy trình kiểm thử để đảm bảo rằng savedInstanceState không rỗng.
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);

// Restore the state.
if (savedInstanceState != null) {
}

Khi Activity được tạo, hệ thống sẽ chuyển trạng thái Bundle sang onCreate() làm đối số duy nhất. Lần đầu tiên gọi onCreate() và ứng dụng khởi động, Bundlenull (không có trạng thái hiện tại trong lần đầu ứng dụng khởi động). Các phương thức gọi tiếp theo của onCreate() có một gói được điền sẵn dữ liệu mà bạn đã lưu trữ trong onSaveInstanceState().

  1. Trong quy trình kiểm tra đó, hãy bỏ chế độ hiển thị hiện tại (giá trị true hoặc false) ra khỏi Bundle bằng khoá "reply_visible".
if (savedInstanceState != null) {
    boolean isVisible =
                     savedInstanceState.getBoolean("reply_visible");
}
  1. Thêm quy trình kiểm tra bên dưới dòng trước đó cho biến isVisible.
if (isVisible) {
}

Nếu có khoá reply_visible ở trạng thái Bundle (và do đó isVisibletrue) thì bạn phải khôi phục trạng thái.

  1. Trong quy trình kiểm tra isVisible, hãy cho thấy tiêu đề.
mReplyHeadTextView.setVisibility(View.VISIBLE);
  1. Nhận tin nhắn trả lời bằng văn bản của Bundle bằng khoá "reply_text" rồi đặt TextView trả lời để cho thấy chuỗi đó.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
  1. Cũng thực hiện tương tự để TextView trả lời xuất hiện:
mReplyTextView.setVisibility(View.VISIBLE);
  1. Chạy ứng dụng. Hãy thử xoay thiết bị hoặc trình mô phỏng để đảm bảo tin nhắn trả lời (nếu có) vẫn xuất hiện trên màn hình sau khi Activity được tạo lại.

Đoạn mã giải pháp cho nhiệm vụ 2

Các đoạn mã sau đây là giải pháp cho nhiệm vụ này.

MainActivity

Các đoạn mã sau đây là đoạn mã đã thêm trong MainActivity chứ không phải toàn bộ lớp.

Phương thức onSaveInstanceState():

@Override
public void onSaveInstanceState(Bundle outState) {
   super.onSaveInstanceState(outState);
   // If the heading is visible, message needs to be saved.
   // Otherwise we're still using default layout.
   if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
       outState.putBoolean("reply_visible", true);
       outState.putString("reply_text",
                      mReplyTextView.getText().toString());
   }
}

Phương thức onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

   Log.d(LOG_TAG, "-------");
   Log.d(LOG_TAG, "onCreate");

   // Initialize all the view variables.
   mMessageEditText = findViewById(R.id.editText_main);
   mReplyHeadTextView = findViewById(R.id.text_header_reply);
   mReplyTextView = findViewById(R.id.text_message_reply);

   // Restore the saved state.
   // See onSaveInstanceState() for what gets saved.
   if (savedInstanceState != null) {
       boolean isVisible =
                     savedInstanceState.getBoolean("reply_visible");
       // Show both the header and the message views. If isVisible is
       // false or missing from the bundle, use the default layout.
       if (isVisible) {
           mReplyHeadTextView.setVisibility(View.VISIBLE);
           mReplyTextView.setText(savedInstanceState
                                  .getString("reply_text"));
           mReplyTextView.setVisibility(View.VISIBLE);
       }
   }
}

Dự án hoàn chỉnh:

Dự án Android Studio: TwoActivitiesLifecycle

5. Thử thách lập trình

Thử thách: Tạo một ứng dụng danh sách mua sắm đơn giản có hoạt động chính cho danh sách người dùng đang xây dựng và hoạt động thứ hai cho danh sách mặt hàng mua sắm phổ biến.

  • Hoạt động chính phải chứa danh sách cần xây dựng và nên được tạo bằng 10 phần tử TextView trống.
  • Nút Add Item () trên hoạt động chính sẽ khởi chạy hoạt động thứ hai, trong đó chứa danh sách mặt hàng mua sắm phổ biến (Cheese (Phô mai), Rice (Gạo), Apples (Táo), v.v.). Sử dụng phần tử Button để cho thấy các mặt hàng.
  • Thao tác chọn một mặt hàng sẽ đưa người dùng trở lại hoạt động chính rồi cập nhật một TextView trống để thêm mặt hàng đã chọn.

Sử dụng Intent để truyền thông tin từ Activity sang phần tử khác. Đừng quên lưu trạng thái hiện tại của danh sách mua sắm khi người dùng xoay thiết bị.

6. Tóm tắt

  • Vòng đời hoạt động là tập hợp trạng thái mà Activity di chuyển qua, bắt đầu từ khi được tạo lần đầu và kết thúc khi hệ thống Android xác nhận lại tài nguyên cho Activity đó.
  • Khi người dùng chuyển từ Activity sang một phần tử khác, bên trong và bên ngoài ứng dụng của bạn, mỗi loại Activity di chuyển giữa các trạng thái trong vòng đời Activity.
  • Mỗi trạng thái trong vòng đời Activity đều có một phương thức gọi lại tương ứng mà bạn có thể ghi đè trong lớp Activity.
  • Có các phương thức vòng đời onCreate(), onStart(), onPause(), onRestart(), onResume(), onStop(), onDestroy().
  • Thao tác ghi đè phương thức gọi lại trong vòng đời cho phép bạn thêm hành vi xảy ra khi Activity chuyển đổi sang trạng thái đó.
  • Bạn có thể thêm các phương thức ghi đè khung vào các lớp của mình trong Android Studio bằng cách chọn Code > Override (Mã > Ghi đè).
  • Các thay đổi về cấu hình thiết bị (chẳng hạn như xoay) dẫn đến việc Activity bị huỷ và tạo lại như mới.
  • Một phần của trạng thái Activity được giữ nguyên khi thay đổi cấu hình, bao gồm cả các giá trị hiện tại của phần tử EditText. Đối với mọi dữ liệu khác, bạn phải tự lưu dữ liệu đó một cách rõ ràng.
  • Lưu trạng thái thực thể Activity trong phương thức onSaveInstanceState().
  • Dữ liệu trạng thái thực thể được lưu trữ dưới dạng các cặp giá trị/khoá đơn giản trong Bundle. Sử dụng các phương thức Bundle để đưa dữ liệu vào cũng như lấy lại dữ liệu qua Bundle.
  • Khôi phục trạng thái của thực thể trong onCreate() (cách ưu tiên) hoặc onRestoreInstanceState().

7. Khái niệm có liên quan

Tài liệu về khái niệm có liên quan được trình bày trong nội dung 2.2: Vòng đời và trạng thái hoạt động.

8. Tìm hiểu thêm

Tài liệu về Android Studio:

Tài liệu dành cho nhà phát triển Android:

9. Bài tập về nhà

Phần này liệt kê các bài tập về nhà cho học viên của lớp học lập trình này trong phạm vi khoá học có người hướng dẫn. Người hướng dẫn phải thực hiện các việc sau đây:

  • Giao bài tập về nhà nếu cần.
  • Trao đổi với học viên về cách nộp bài tập về nhà.
  • Chấm điểm bài tập về nhà.

Người hướng dẫn có thể sử dụng các đề xuất này ít hoặc nhiều tuỳ ý và nên giao cho học viên bất kỳ bài tập về nhà nào khác mà họ cảm thấy phù hợp.

Nếu bạn đang tự học các lớp học lập trình, hãy sử dụng những bài tập về nhà này để kiểm tra kiến thức của mình.

Tạo và chạy ứng dụng

  1. Tạo một ứng dụng có bố cục chứa bộ đếm TextView, Button để tăng bộ đếm và EditText. Hãy xem ảnh chụp màn hình dưới đây làm ví dụ. Bạn không cần phải sao chép chính xác bố cục.
  2. Thêm một trình xử lý lượt nhấp cho Button để tăng bộ đếm.
  3. Chạy ứng dụng và tăng bộ đếm. Nhập nội dung văn bản vào EditText.
  4. Xoay thiết bị. Xin lưu ý rằng bộ đếm được đặt lại, nhưng EditText sẽ không được đặt lại.
  5. Triển khai onSaveInstanceState() để lưu trạng thái hiện tại của ứng dụng.
  6. Cập nhật onCreate() để khôi phục trạng thái của ứng dụng.
  7. Đảm bảo rằng khi bạn xoay thiết bị, trạng thái ứng dụng được giữ nguyên.

ebaf84570af6dd46.png

Trả lời các câu hỏi sau

Câu hỏi 1

Nếu bạn chạy ứng dụng bài tập về nhà trước khi triển khai onSaveInstanceState(), điều gì sẽ xảy ra khi bạn xoay thiết bị? Vui lòng chọn một đáp án:

  • EditText không còn chứa văn bản bạn nhập, nhưng bộ đếm được giữ nguyên.
  • Bộ đếm được đặt lại về 0 và EditText không còn chứa văn bản bạn nhập.
  • Bộ đếm được đặt lại về 0 nhưng nội dung của EditText được giữ nguyên.
  • Bộ đếm và nội dung của EditText được giữ nguyên.

Câu hỏi 2

Phương thức vòng đời Activity nào được gọi khi xảy ra thay đổi cấu hình thiết bị (chẳng hạn như xoay)? Vui lòng chọn một đáp án:

  • Android tắt ngay Activity bằng cách gọi onStop(). Mã nguồn của bạn phải khởi động lại Activity.
  • Android tắt Activity bằng cách gọi onPause(), onStop()onDestroy(). Mã nguồn của bạn phải khởi động lại Activity.
  • Android tắt Activity bằng cách gọi onPause(), onStop()onDestroy(), sau đó khởi động lại phần tử này, gọi onCreate(), onStart()onResume().
  • Android gọi ngay cho onResume().

Câu hỏi 3

onSaveInstanceState() được gọi khi nào trong vòng đời Activity? Vui lòng chọn một đáp án:

  • onSaveInstanceState() được gọi trước phương thức onStop().
  • onSaveInstanceState() được gọi trước phương thức onResume().
  • onSaveInstanceState() được gọi trước phương thức onCreate().
  • onSaveInstanceState() được gọi trước phương thức onDestroy().

Câu hỏi 4

Phương thức vòng đời Activity nào phù hợp nhất để lưu dữ liệu trước khi kết thúc hoặc huỷ Activity? Vui lòng chọn một đáp án:

  • onPause() hoặc onStop()
  • onResume() hoặc onCreate()
  • onDestroy()
  • onStart() hoặc onRestart()

Gửi ứng dụng của bạn để được chấm điểm

Hướng dẫn dành cho học viên

Kiểm tra để đảm bảo ứng dụng có các đặc điểm sau:

  • Cho thấy một bộ đếm, một Button để tăng bộ đếm đó và một EditText.
  • Khi nhấp vào Button, bộ đếm sẽ tăng 1.
  • Khi xoay thiết bị, cả bộ đếm và trạng thái EditText đều được giữ nguyên.
  • Quy trình triển khai MainActivity.java sử dụng phương thức onSaveInstanceState() để lưu trữ giá trị bộ đếm.
  • Quy trình triển khai onCreate() kiểm tra sự tồn tại của Bundle outState. Nếu Bundle đó tồn tại thì giá trị bộ đếm sẽ được khôi phục và lưu vào TextView.

10. Lớp học lập trình tiếp theo

Để tìm lớp học lập trình tiếp theo trong khoá học Kiến thức cơ bản dành cho nhà phát triển Android (Phiên bản 2), hãy xem tham khảo Lớp học lập trình cho khoá học Kiến thức cơ bản dành cho nhà phát triển Android (Phiên bản 2).

Để biết thông tin tổng quan về khoá học này, bao gồm cả đường liên kết đến chương khái niệm, ứng dụng và trang trình bày, hãy tham khảo Kiến thức cơ bản dành cho nhà phát triển Android (Phiên bản 2).