Lưu và phục hồi trạng thái của Activity trong Android

Phần này tạo một ứng dụng đơn giản tên là SaveAndRestoreState để tìm hiểu việc lưu lại trạng thái của Activity và phục hồi trạng thái của Activity trong vòng đời hoạt động của nó.

Tạo Project – SaveAndRestoreState

Mở Android Studio chọn tạo Project mới, nhập tên ứng dụng là SaveAndRestoreState

Trong cửa sổ tiếp theo chọn Phone and Table và API mong muốn. Bấm tiếp, của sổ Add an Activity to Mobile chọn Empty Activity

Trong của sổ Configure Activity điền tên Activity là: SaveRestoreActivity và layout tên là activity_save_restore như hình dưới. Sau đó Bấm vào Finish

Ta sẽ xây dựng SaveRestoreActivity hiện thị một TextView chứa tên bài học, một nút bấm mà mỗi khi bấm vào thì tên bài học thay đổi. Khi nút bấm được bấm vào thì màu nền thay đổi từ màu ban đầu sang màu Color.GREEN như kết quả sau:

Cập nhật lại layout activity_save_restore.xml thêm TextView và Button với ID tương ứng là message và nextlesson

Tiếp theo cập nhật code Java cho file: SaveRestoreActivity.java như sau:

Bạn có thể nhấn Shift + F10 để thạy chử trên máy ảo, ứng dụng hoạt động như kết quả trên hình.

Lưu lại và phục hồi trạng thái trong Activity

Ứng dụng trên hoạt động có vẻ không có vấn đề gì, tuy nhiên khi bấm đến bài số 5, thì màn hình có dòng chữ : Bai học: 5 và nút bấm có nền GREEN. Đang ở trạng thái này, nếu bạn xoay ngang màn hình thì sau khi ứng dụng quay ngang (giả sử trường hợp này điện thoại bật chế độ cho phép xoay ngang) thì sau khi ứng dụng xoay ngang màn hình hiện thị kết quả không như cũ. Dòng chữ trở về nội dung Bai học: 1 và màu nền nút bấm về màu mặc định.

Điều này xảy ra bởi vì trong vòng đời của Activity như chúng ta đã biết, khi Activity từ màn hình đứng quay ngang nó sẽ hủy Activity cũ (onPause -> onDestroy) rồi tạo Activity mới (gọi lại onCreate) do đó mà trạng thái sẽ trở về như lúc khởi tạo ban đầu.

Trường hợp nữa, khi Activiy không còn hiện thị (onPause) nó nằm trong ngăn xếp hệ thống, nó có thể bị hệ thống Android hủy và khởi tạo lại bất kỳ lúc nào để quản lý tài nguyên (bố nhớ), và thế thì khi Activity quay trở lại nó cũng không còn lưu trạng thái như trước khi đi vào onPause.

Vậy làm thế nào để khi Activity khởi tạo lại do hệ thống thay đổi (ví dụ quay ngang màn hình) mà trạng thái của nó vẫn giữ như trạng thái cũ?

Lưu lại trạng thái với onSaveInstanceState

Rất may là Activity có cơ chế để thực hiện việc này (lưu và phục hồi trạng thái). Trước tiên là khi Activity đi vào onPause, nó sẽ tự động gọi phương thức onSaveInstanceState(Bundle outState), ta chỉ việc nạp chồng phương thức đó, và muốn lưu tạm trạng thái nào thì sẽ đưa vào Bundle outState

Ta sẽ nạp chồng(overrided) phương thức này để lưu lại giá trị của mLession và màu của Button button

Bundle outState cho phép lưu dữ liệu trong nó theo cặp tên/giá trị bằng các phương thức: putInt(), putString(), putBoolean() … tùy theo dữ liệu muốn lưu

Lưu ý khi nạp chồng onSaveInstanceState bạn cần gọi trong nó super.onSaveInstanceState(outState); để các View con trong giao diện cũng có thể lưu và phục hồi trạng thái riêng biệt (vì một số View như TextEdit cũng có cơ chế riêng để lưu và phục hồi trạng thái).

Phục hồi trạng thái ngay tại onCreate

Sau khi trạng thái (dữ liệu tạm) được lưu như trên, ta có thể đọc được khi Activity hoạt động ở vòng đời mới. Các giá trị ta lưu ở outState trong phương thức onSaveInstanceState sẽ quay trở lại onCreate trong savedInstanceState, vậy trong onCreate ta chỉ việc đọc trạng thái trước đây. Ví dụ phục hồi lại giá trị mLesson và màu button

Giờ ứng dụng của chúng ta đã lưu lại trạng thái, khi bạn thử xoay màn hình, sau khi Activiy xoay nó sẽ phục hồi như màn hình trước khi xoay.

Trong đoạn mã trên, luôn cần kiểm tra (savedInstanceState != null) rồi mới đọc giá trị cần phục hồi bởi vì nếu Activiy là khởi đầu mới (không phải kích hoạt lại) thì savedInstanceState = null. Nếu không muốn kiểm tra, có thể không phục hồi ở đây mà tại onRestoreInstanceState

Phục hồi trạng thái tại onRestoreInstanceState(Bundle savedInstanceState)

Mỗi khi OnCreate khởi chạy, nếu có trạng thái được lưu lại thì sau khi gọi onCreate Activity sẽ tự động gọi phương thức onRestoreInstanceState(Bundle savedInstanceState), bạn cũng có thể quá tải phương thức này và đọc dữ liệu cần phục hồi tại savedInstanceState. Ví dụ:

Kết quả cũng tương tự

Sử dụng Bundle

Trong ví dụ trên, đã sử dụng đến đối tượng lớp Bundle để lưu và phục hồi trạng thái. Mục đích của Bundle để truyền dữ liệu giữa các Activity, nó được sử dụng cơ bản bởi Intent

Tạo một đối tượng Bundle

Dữ liệu được đưa vào Bundle khá giống với Map, tức là dữ liệu nào đó sẽ được lưu theo cặp key và giá trị. Dữ liệu được đọc căn cứ vào key lưu trữ đó

Ví dụ:

Các phương thức để lưu dữ liệu như: putInt, putBoolean, putString, putFloat … tương ứng có các phương thức đọc dữ liệu như getInt, getBoolean, getString, getFloat …

Bài viết khác

Hồ Diên Lợi
Đến với CNTT là tình cờ, tuy nhiên khi đã tham gia rồi thì mới biết đây chính là đam mê, hy vọng dịch bệnh Covid-19 sẽ qua, để chia sẽ đam mê công nghệ đến nhiều người hơn!

DANH SÁCH BÀI HỌC