Android Architecture Components: ViewModel

Hôm nay tôi muốn nói đến ViewModel trong Android Architecture Components.Như bạn biết, thành phần này rất hữu ích khi bạn muốn quản lý và xử lý dữ liệu cho giao diện của bạn (Ví dụ Activity hoặc Fragment). Bây giờ thì cùng thử xem triển khai ViewModel vào trong dự án của bạn thế nào nhé.

1. Lời mở đầu

Giả sử bạn có một số Activity. Có thể bạn cũng sẽ có một số Object để lưu trữ và cung cấp dữ liệu cho UI (như Presenter được biết đến từ MVP hoặc ViewModel từ MVVM). Thật không may, người dùng có thể xoay điện thoại của mình ಠ_ಠ Điều gì sẽ xảy ra sau đó? Activity của bạn sẽ được tạo lại. Và sẽ có người giữ dữ liệu giao diện người dùng của bạn. Có ý nghĩa gì với bạn? Bạn cần nhớ về chuyển dữ liệu đến Activity đã được tạo lại, nếu không, bạn cần khôi phục lại một lần nữa (vì vậy bạn sẽ thực hiện cuộc gọi thứ hai vào cơ sở dữ liệu hoặc API) Bạn cần phải biết việc rò rỉ bộ nhớ có thể khiến người giữ dữ liệu UI của bạn sống lâu hơn Activity(và bạn không muốn điều đó!) Giải pháp cho những vấn đề đó là gì? Tất nhiên một ViewModel 👍

2. ViewModel

ViewModel lưu trữ dữ liệu của bạn cho UI và nó cũng có vòng đời của nó (lifecycle-aware). hãy nhìn vào ảnh gif bên dưới : ViewModel có thể tồn tại qua những thay đổi của configuration. Điều này có nghĩa là ngay cả sau khi Activity bị destroyed và được tạo lại sau khi xoay vòng điện thoại, bạn vẫn có cùng một ViewModel với cùng một dữ liệu. Nhờ đó:

  • Bạn không cần phải lo lắng về vòng đời của Data Holder UI. ViewModel sẽ được tạo ra tự động bởi một Factory và bạn không cần phải tự tạo ra nó và tự hủy nó.
  • Dữ liệu sẽ luôn được cập nhật - Bạn sẽ nhận được dữ liệu tương tự sau khi xoay điện thoại như trước đây. Nhờ đó bạn không cần truyền dữ liệu thủ công vào Activity mới hoặc thực hiện gọi lại vào cơ sở dữ liệu. Tất cả đã xong cho bạn!
  • Dữ liệu sẽ chờ bạn - Nếu bạn thực hiện cuộc gọi API, bạn xoay điện thoại và kết quả sẽ được phân phối trước khi Activity được tạo lại, bạn chắc chắn dữ liệu được lưu trữ trong ViewModel và bạn có thể nhận được ngay sau khi Activity được khởi tạo lại.

3. Làm thế nào để dùng được ViewModel

Để dùng được ViewModel rất đơn giản. Cùng nhìn những dòng ví dụ bên dưới này :

public class UsersViewModel extends ViewModel {
 
     private List<User> userList;
 
     public List<User> getUserList() {
        if (userList == null) {
             usersList = loadUsers();
         }
         return userList;
     }
 
     private List<User> loadUsers() {
         // do something to load users
     }
 }

Ở đây chúng ta có một vài dữ liệu cho UI.Trong trường hợp này, đó là danh sách người dùng, chúng ta tải bằng cách nào đó từ nguồn bên ngoài. Để có ViewModel, chúng ta chỉ cần extends ViewModel. Và đó là nó! Bây giờ, chúng ta có thể có UserViewModel của chúng ta trong Activity:

public class UsersActivity extends AppCompatActivity {
 
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
 
         UsersViewModel usersViewModel =
             ViewModelProviders.of(this).get(UsersViewModel.class);
 
         showUsers(usersViewModel.getUserList());
     }
 }

Để có được ViewModel của chúng ta, chúng ta sử dụng ViewModelProviders.of (). Đó là Factory của ViewModels và nhờ đó chúng ta không cần phải lo lắng về vòng đời của ViewModel. Sau khi nhận được UsersViewModel, chúng ta có thể lấy một số dữ liệu từ nó sử dụng phương thức usersViewModel.getUserList ().

4. ViewModel vs onSaveInstanceState()

Sau khi giới thiệu ViewModel này xong nhiều khi bạn tự hỏi thế còn về onSaveInstanceState() thì sao đúng không. onSaveInstanceState() thường được sử dụng để lưu trữ dữ liệu khi xảy ra sự kiện configuration change. Thì tôi cũng trả lời luôn tại đây là ViewModel không thay thế onSaveInstStanceState(). ViewModel chỉ được lưu trữ cho Activity được tạo lại do orientation change. Ngoài ra, onSaveInstanceState () có thể tồn tại qua hoạt động bị hệ thống xóa đi (ví dụ: khi ứng dụng chuyển sang nền và hệ thống quyết định giải phóng bộ nhớ). Mục đích của cả hai chúng là gì? Tất nhiên, chúng ta chỉ có thể sử dụng onSaveInstanceState (), nhưng tiếc là nó lại có vài nhược điểm:

  • Trong onSaveInstStanceState () chúng ta chỉ có thể lưu trữ số lượng nhỏ dữ liệu
  • Dữ liệu cần phải là Parcelable, vì vậy nó không phải dễ dàng để thiết lập và khôi phục các giá trị.

5. Vì vậy khi nào thì chúng ta nên sử dụng onSaveInstanceState()

  • Sử dụng ViewModel để lưu trữ dữ liệu thực tế cho UI (ví dụ: danh sách bạn bè cho người dùng)
  • Sử dụng onSaveInstanceState () để lưu trữ dữ liệu cần thiết để nhận dữ liệu cho Activity sau khi hệ thống xóa đi (ví dụ: id của người dùng hiện tại).

Nhờ đó, chúng ta sẽ phải xử lý cả hai trường hợp. Nếu Activity của chúng ta sẽ bị kill bởi một hệ thống, chúng ta sẽ có thể lấy danh sách bạn bè của người dùng, bởi vì chúng ta có một id của người dùng. Và khi chúng ta nhận được danh sách, chúng ta có thể lưu trữ nó trong ViewModel và sử dụng nó ngay cả sau khi xảy ra sự kiện orientation change

Đó chính là nó ViewModel! Tôi hy vọng bạn thích bài đăng này. Nếu bạn đã làm, đừng quên upvote cho mình nhé.

All Rights Reserved