Android Java

Suy luận về trạng thái khi vòng đời Android thay đổi

Phân biệt xoay màn hình, thu hồi tiến trình và mở phiên mới. Kiểm tra khôi phục dữ liệu và phản hồi bất đồng bộ.

Suy luậnTrung cấp16 phút đọcJava · AndroidX

Thích và đánh giá Bình luận và hỏi đáp
Chọn nơi lưu theo biến cố cần vượt qua: thay đổi cấu hình, khôi phục tác vụ hoặc mở một phiên mới.
Chọn nơi lưu theo biến cố cần vượt qua: thay đổi cấu hình, khôi phục tác vụ hoặc mở một phiên mới. Mở hình lớn ↗

1. Hỏi trạng thái cần sống qua biến cố nào

Trong màn hình tìm học phần, sinh viên chọn một mã lớp, nhập cụm từ lọc và có thể sửa ghi chú. Sau khi xoay màn hình, họ mong danh sách vẫn lọc đúng và màn hình vẫn hiển thị lớp vừa chọn. Nếu hệ điều hành thu hồi tiến trình lúc ứng dụng chạy nền, khi quay lại họ mong mở đúng lớp. Nếu đã bấm Lưu ghi chú, họ mong đọc lại được ghi chú sau khi mở ứng dụng từ đầu. Ba kỳ vọng dẫn đến ba cách quản lý trạng thái.

Dữ liệuĐặt ở đâuLý do
Danh sách đã tải, kết quả tính tạmViewModel trong bộ nhớDùng lại khi thay đổi cấu hình. Có thể tải lại nếu tiến trình bị hủy.
Mã lớp, từ khóa lọcSavedStateHandleGiữ lượng nhỏ dữ liệu cần để dựng lại màn hình khi hệ thống khôi phục tác vụ.
Ghi chú đã lưu hoặc bản nháp cần tồn tại lâuKho dữ liệu bền vữngNgười dùng cần đọc lại dữ liệu trong một phiên mở mới.

Saved state gắn với tác vụ được hệ thống khôi phục. Không coi đây là cơ chế lưu lâu dài sau khi người dùng bỏ tác vụ, buộc dừng hoặc mở một phiên mới. Bản nháp cần tồn tại qua những tình huống này phải được ghi vào kho bền vững.

Một câu hỏi thiết kế thực dụng là “nếu giá trị biến mất, có thể tái tạo từ nguồn nào?”. Mã lớp đủ nhỏ để lưu và đủ để truy vấn kho dữ liệu. Một danh sách dài các học phần thường có thể tải lại từ mã và từ khóa. Việc ghi cả danh sách vào trạng thái khôi phục vừa tốn tài nguyên vừa dễ dẫn tới hiển thị dữ liệu đã cũ.

2. Lưu khóa tái tạo thay cho toàn bộ màn hình

Môi trường thực hành. Mẫu Java dùng trong dự án Android với AndroidX và các tài nguyên giao diện được mô tả trong bài. Tệp này chưa phải một ứng dụng Android hoàn chỉnh.

Java · AndroidX · DraftViewModel.javaTải mã nguồn
// Ví dụ ViewModel cho màn hình sửa một học phần.
// Cần AndroidX Lifecycle ViewModel SavedState trong dự án Android.
import androidx.lifecycle.LiveData;
import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;

public final class DraftViewModel extends ViewModel {
    private static final String COURSE_ID = "courseId";
    private static final String QUERY = "query";
    private final SavedStateHandle state;

    public DraftViewModel(SavedStateHandle state) {
        this.state = state;
    }

    public void selectCourse(String id) {
        state.set(COURSE_ID, id);
    }

    public LiveData<String> courseId() {
        return state.getLiveData(COURSE_ID);
    }

    public void setQuery(String query) {
        state.set(QUERY, query);
    }

    public LiveData<String> query() {
        return state.getLiveData(QUERY, "");
    }
}

Đây là lớp Java minh họa dùng AndroidX trong một dự án Android. Khi lấy ViewModel bằng ViewModelProvider với nhà cung cấp hỗ trợ saved state, SavedStateHandle giữ các khóa nhỏ. Activity hoặc Fragment quan sát courseId() và truy vấn lại kho theo mã lớp. Khi người dùng đổi từ khóa, màn hình gọi setQuery và lọc danh sách theo trạng thái mới. Mẫu này tập trung vào ViewModel. Phần giao diện và lớp kho được cài theo dự án sử dụng.

Nếu truy vấn là bất đồng bộ, thử kịch bản chọn lớp A rồi chuyển nhanh sang B. Phản hồi cho A có thể về sau B. Màn hình cần hủy truy vấn cũ hoặc kiểm tra mã của phản hồi với mã đang chọn trước khi cập nhật giao diện. Nếu chỉ nhìn kết quả khi kết nối nhanh, lỗi cạnh tranh này rất khó thấy.

3. Tách khôi phục giao diện khỏi lưu dữ liệu

Giả sử người dùng sửa ghi chú, tiến trình bị thu hồi, hệ thống dựng lại màn hình và mã lớp được khôi phục. Việc mở được đúng lớp chỉ chứng minh rằng khóa điều hướng đã được giữ. Nội dung ghi chú có thể vẫn mất nếu ứng dụng chỉ giữ bản nháp trong bộ nhớ. Nếu yêu cầu là giữ bản nháp qua cả lần mở mới, hãy định nghĩa thời điểm lưu bản nháp, định danh bản nháp và cách khôi phục sau lỗi ghi.

Ngược lại, nếu kho đã ghi thành công nhưng giao diện chưa nhận kết quả trước khi tiến trình dừng, lần mở lại nên đọc trạng thái từ kho. Không nên dựa vào việc nút Lưu lần trước còn hiển thị trạng thái “đang lưu”. Nguồn có thẩm quyền về dữ liệu đã ghi là kho dữ liệu, còn nguồn có thẩm quyền về lớp người dùng đang xem là trạng thái màn hình.

4. Xây ma trận kiểm thử theo biến cố

  1. Xoay màn hình trong lúc tìm kiếm và đối chiếu lớp, từ khóa cùng danh sách hiển thị.
  2. Để ứng dụng chạy nền, mô phỏng hệ thống thu hồi tiến trình trong môi trường thử và mở lại từ danh sách tác vụ. Đối chiếu khóa khôi phục và kết quả tải lại.
  3. Ghi một ghi chú, mở ứng dụng ở phiên mới và truy vấn lại lớp. Kiểm tra kho dữ liệu riêng với kiểm tra trạng thái màn hình.
  4. Tạo phản hồi bất đồng bộ sai thứ tự và xác nhận dữ liệu của lớp A không ghi đè giao diện khi lớp B đang được chọn.

Đọc thêm tại Android Developers · Lưu trạng thái giao diện.