Saving state trong Android

I, Lời nói đầu

  • Xin chào mọi người, hôm nay mình xin chia sẻ 1 vấn đề mà mọi người rất quen thuộc: saving state trong Android.
  • Android architecture compoent ra đời cùng với Lifecycle (ViewModel, LiveData), mọi người sẽ thường store data và restore data trong hầu hết các case xảy ra với app của mình.
  • Nhưng liệu quan điểm có thực sự đúng ? Còn những nguy cơ nào còn có thể xảy để chúng ta có thể handle tất cả các trường hợp ?

2, Saving state

  • Có thể mọi người đã biết rằng Activity và Fragment sẽ bị destroy bởi 1 trong 3 cách sau:
  • 1, User điều hướng để kết thúc vĩnh viễn: user nhấn back button hoặc có 1 lời gọi finish(). Trong trường hợp này, Activity và Fragment sẽ bị finish và không được recreate lại bởi Android system.
  • 2, Configuration change: Hay xảy ra nhất đó chính là khi rotate screen. Ngoài ra, change language hay keyboard cũng là những nguyên nhân tạo ra configuration change. Trong trường hợp này, Android system sẽ tự động recreate lại Activity hay Fragment đó.
  • 3, App của bạn bị put xuống dưới background và process của App bị kill: Trường hợp này thường chúng ta không để ý tới nhưng nó luôn là 1 nguy cơ tiềm tàng. Khi device cần thêm memory thì nó sẽ cần giải phóng memory hiện đang không dùng tới, nếu app đang ở trong background (onStop()) thì priority của Process của app sẽ bị giảm xuống. Activity và Fragment trong trường hợp này cũng sẽ bị finish nhưng khi bạn back lại app thì activity sẽ được recreate lại. Thường trong trường hợp này người dùng cũng như newbie sẽ không chú ý tới nhưng sau phía dưới thực sự đã diễn ra 1 quá trình finish và recreate lại Activity và Fragment của bạn.
  • Trong trường hợp thứ 2 và thứ 3, Android system sẽ recreate lại Activity.
  • Trong trường hợp thứ 2, ViewModel sẽ chỉ giúp cho bạn saving state trong mà thôi bởi vì trong trường hợp này Activity sẽ chỉ bị chạy onDestroy() chứ không bị finish. Nghĩa là ViewModel trong trường hợp này vẫn sống nhăn răng 😅.
  • Trong trường hợp thứ 3, Activity chạy vào onDestroy() và đồng thời nó cũng sẽ bị finish do đó ViewModel cũng sẽ bị clear luôn 😂. Tức là trong trường hợp này chúng ta sẽ không thể sử dụng được ViewModel. Giải pháp của chúng ta sẽ là sử dụng onSaveInstanceState() hoặc mới hơn sẽ là ViewModel Saved State module.
  • Bảng bên dưới sẽ giải thích những gì mình nói phía trên:

3, ViewModel Saved State module vs onSaveInstanceState()

  • onSaveInstanceState() là callback để lưu trữ UI data được sử dụng trong 2 trường hợp:
  • 1, App ở trong background làm cho process của app bị giảm mức priority: process death.
  • 2, Configuration change.
  • onSaveInstanceState() được gọi trong trường hợp Activity chạy onStop() không phải là finish().
  • Hơn nữa, onSaveInstanceState() chỉ được design để store data nhỏ như String, Int chứ không phải là những data phức tạp như: Bitmap... bởi vì nó yêu cầu serialization và deserialization và 2 quá trình này rất tốn memory và cũng rất chậm.
  • ViewModel Saved State Module cũng giúp chúng ta giải quyết vấn đề: process death. Với công cụ này tất cả sẽ được sử lý chỉ ở trong ViewModel và không còn phải liên quan tới Activity nữa. Và giờ ViewModel đã thực sự xử lý và lưu trữ tất cả các data liên quan tới UI.
  • ViewModel Saved State Module sử dụng SavedStateHandle. Bất kể data nào bạn phải store ở trong onSaveInstanceState() giờ có thể hoàn toàn chuyển sang SavedStateHandle.

4, Tổng kết

All Rights Reserved