12/08/2018, 17:41

CÁC ỨNG DỤNG REACTIVE VỚI MODEL-VIEW-INTENT - PHẦN MODEL (tiếp)

2. Xoay màn hình Xoay màn hình trong android đôi khi gặp khá nhiều vấn đề khó xử lý. Cách giải quyết đơn giản nhất là bỏ qua nó (nghe hơi nực cười). Khi xoay màn hình thì chỉ cần reload mọi thứ, đây cũng là một cách xử lý hợp lệ. Phần lớn thời gian, các ứng dụng làm việc offline, vì thế có rất ...

2. Xoay màn hình

Xoay màn hình trong android đôi khi gặp khá nhiều vấn đề khó xử lý. Cách giải quyết đơn giản nhất là bỏ qua nó (nghe hơi nực cười). Khi xoay màn hình thì chỉ cần reload mọi thứ, đây cũng là một cách xử lý hợp lệ. Phần lớn thời gian, các ứng dụng làm việc offline, vì thế có rất nhiều data được lấy từ local database hoặc các local cache khác. Do đó, có thể loading data siêu nhanh sau khi xoay màn hình. Tuy nhiên, tôi không thíc nhìn thấy một loading indicator, ngay cả khi nó chỉ có vài milisecond, bởi vì nó làm cho người dùng cảm thấy ứng dụng không được liền mạch, mượt mà.Do đó, lời khuyên cho mọi người hãy bắt đầu sử dụng MVP với "retaining presenter" để View có thể được tách riêng ra (và có thể bị destroyed) trong suốt quá trình xoay màn hình, trong khi đó Presenter vẫn tồn tại trong memory và sau đó View được gắn lại với Presenter. Khái niệm này có thể tương tự với MVVM với RxJava, nhưng có lưu ý là View có thể đã bị hủy kết nối với ViewModel. Bạn có thể làm việc quanh chủ đề này, cho ví dụ. Trong MVVM có ràng buộc dữ liệu (data binding) với một ViewModel được liên kết trực tiếp với View. Để tránh leak memory, thì chúng ta phải hủy ViewModel khi xoay màn hình.

Nhưng có vấn đề với retaining Presenter (hoặc ViewModel) là: Làm thế nào để đưa View về đúng trạng thái trước khi xoay màn hình, bao gồm cả View và Presenter. Tôi đã viết một thư viện MVP gọi là Mosby với một feature gọi là ViewState về cơ bản nó đồng bộ hóa trạng thái business logic với View. Moxy là một thư viện MVP khác, đã thực thi một giải pháp khác bằng cách sử dụng “commands” để giữ state của View sau khi xoay màn hình:

Chắc chắn sẽ có những phương pháp khác để xử lý vấn đề về trạng thái của View. Tuy nhiên thì thư viện trên cũng đã cố gắng giải quyết vấn đề về state mà ta đã đưa ra bên trên.

Vì vậy, một lần nữa, một Model cái mà phản ánh State hiện tại và chính xác một method để render. Vấn đề này được giải quyết dễ như là mình gọi getView().render(PersonsModel)

3. Navigation on the back stack

Có một Presenter (hoặc ViewModel) có cần phải được giữ lại khi View không được sử dụng nữa? Ví dụ, nếu một Fragment (View) đã được thay thế bằng Fragment khác khi người dùng di chuyển đến một màn hình khác, tiếp đó không có View nào được gắn vào Presenter. Hiển nhiên là nếu không có View nào được gắn vào Presenter thì dữ liệu không thể update được từ Presenter đến View do đó View không thể hiển thị được dữ liệu mới nhất. Trong trường hợp người quay trở lại màn hình trước (ví dụ như nhấn nút back để quay lại) ? Thì có phải reload lại data hay không hay sử dụng Presenter đã có sẵn trước đó ? Thông thường thì sẽ là quay trở lại trạng thái trước đó (pop back stask), trạng thái hiển thị giống như trước khi di chuyển màn hình. Về cơ bản thì chỉ là lấy lại trạng thái của View như đã nói trong mục 2. Do đó, giải pháp đơn giản là : Với một "Model" đại diện cho một state thì chỉ cần gọi getView(). render(PersonsModel) để hiển thị lên View khi back stack.

4. Process death

Việc để app bị crash hay process death thì chả tốt tẹo nào đối với việc phát triển ứng dụng android dó đó chúng ta cần support việc restore state (và Presenters hoặc ViewModels) sau khi process death. Có một vài nguyên nhân dẫn đến tình trạng process death: hệ điều hành Android cần nhiều tài nguyên hơn cho các ứng dụng khác hoặc được chuyển sang sử dụng ở chế độ tiết kiệm pin. Nhưng điều này sẽ không bao giờ xảy ra khi ứng dụng của bạn đang chạy chạy background và đang được người dùng sử dụng. Nếu bạn thực sự cần làm việc ở chế độ background, hãy sử dụng Service đây là cách duy nhất để báo hiệu cho hệ điều hành biết ứng dụng của bạn vẫn “actively used”. Nếu xảy ra process death, Android sẽ cung cấp một vài callbacks như onSaveInstanceState () để lưu trạng thái. Một lần nữa phải nhắc đến State. Có nên lưu thông tin của View vào Bundle? State của Presenter thì sao? ... túm lại ta chỉ cần một Model class cái mà đại diện cho tất cả state. Và dễ để lưu lại Model này vào Bundle và để restore lại sau đó . Tuy nhiên bạn cũng có thể reload lại màn hình này giống như lúc bắt đầu vào. Giả sử như ứng dụng NewsReader hiển thị danh sách các bài báo. Khi ứng dụng đã bị kill và lưu lại state và 6 giờ sau, người dùng mở lại ứng dụng, trạng thái được khôi phục, nhưng lúc này dữ liệu đã không còn là nhà mới nhất.

Bài viết được dịch từ http://hannesdorfmann.com/android/mosby3-mvi-1

0