0

[Android] Dẹp loạn mớ bòng bong Intent/Fragment với Navigation Component: Khi Mobile học lỏm Backend

Chào anh em, lại là mình đây.

Lâu nay toàn hầu chuyện anh em dưới tầng đáy backend rùi, hôm nay mình ngoi lên tầng giao diện, đổi gió sang mảng Mobile (cụ thể là Android) một chút nhé.

Nếu anh em nào từng làm web nhảy sang nghịch Android, chắc chắn sẽ bị "sốc văn hóa" ở cái màn chuyển trang (routing). Ở web, ví dụ anh em ôm Laravel đi, mọi thứ dễ thở vô cùng. Muốn biết luồng đi của app, chỉ cần mở file routes/web.php ra là thấy cả một bầu trời chân lý. Nhìn vào là biết ngay URL nào trỏ vào Controller nào.

Còn Android ngày xưa thì sao? Úi giời ơi, nó là một mớ hỗn độn!

  • Từ Activity A sang Activity B: Khai báo Intent, nhét data vào Bundle, rồi startActivity().
  • Chơi hệ Fragment thì còn thảm họa hơn: Nào là FragmentManager, beginTransaction(), replace(), addToBackStack(), rồi nhớ commit(). Quên commit một phát là app lăn đùng ra crash không kịp ngáp. Lịch sử điều hướng (back stack) thì lộn tùng phèo, bấm nút Back trên điện thoại mà app thoát luôn là chuyện cơm bữa.

Để cứu rỗi những tâm hồn dev đang gào thét, Google đã tung ra "chân ái" mang tên Navigation Component, và trái tim của nó chính là Navigation Graph.

Navigation Graph là cái quái gì?

Nôm na thế này, Navigation Graph (thường là một file XML như nav_graph.xml) sinh ra để làm cái việc mà web.php làm cho Laravel: Gom tất cả các luồng chuyển trang (routing) vào một chỗ duy nhất.

Thay vì để code chuyển trang nằm rải rác ở hàng chục file Java/Kotlin khác nhau, bây giờ anh em khai báo tất cả các "trang" (gọi là Destination) và "đường đi" giữa chúng (gọi là Action) vào một cái file XML này.

Điều tuyệt vời nhất? Android Studio cung cấp hẳn một cái giao diện kéo thả (Visual Editor) cho Navigation Graph.

Nhìn vào cái hình trên, sếp của bạn (thậm chí chả biết tí code nào) cũng có thể hiểu được: "À, từ trang Home bấm vào nút này sẽ bay sang trang Detail, từ Detail bay sang trang Settings". Cực kỳ trực quan!

Bộ ba quyền lực của Navigation Component

Để cái bản đồ (Nav Graph) này hoạt động được, nó cần sự phối hợp của một tổ đội 3 người:

  1. Navigation Graph (Cái bản đồ): Chính là file XML chứa thông tin các màn hình và đường đi như mình vừa nói.
  2. NavHost (Cái khung tranh): Thường là một cái FragmentContainerView nằm trong Activity chính (MainActivity). Nó đóng vai trò như một cái thùng rỗng. Khi anh em chuyển trang, nội dung của các trang sẽ được lôi từ Graph và "nhét" vào cái thùng này.
  3. NavController (Thằng tài xế): Đây là object thực thi lệnh. Khi anh em muốn sang trang khác, anh em bảo thằng tài xế: "Ê, chở tao đi theo con đường A (Action A)". Nó sẽ tự biết phải bốc cái Fragment nào nhét vào NavHost, tự lo luôn cái vụ nút Back (Back Stack) cho anh em.

Code thực tế nó gọn gàng đến mức cảm động:

// Tìm thằng tài xế và bảo nó chạy theo cái Action tên là 'action_home_to_detail'
findNavController().navigate(R.id.action_home_to_detail)

Tại sao nên vứt hết Intent cũ đi và xài Nav Graph?

Ngoài cái chuyện code ngắn và trực quan, Navigation Graph còn giải quyết triệt để 2 cái "ung nhọt" cực lớn của Android:

1. Safe Args - Khắc tinh của NullPointerException

Ngày xưa truyền data giữa 2 màn hình bằng Bundle nó rén vô cùng. Màn hình A nhét một cái String với key là USER_ID. Sang màn hình B, anh em gõ nhầm key thành USER_IDD, thế là nhận về cái null chà bá, app crash.

Nav Graph đi kèm với một plugin tên là Safe Args. Anh em khai báo thẳng trên XML là: "Màn hình Detail cần một biến tên là userId, kiểu Integer". Ngay lập tức, lúc build code, nó sẽ tự sinh ra một cái class bắt anh em phải truyền đúng kiểu Int vào. Cố tình truyền String hoặc quên không truyền? Báo lỗi đỏ loét ngay từ lúc gõ code (Compile time) chứ không đợi đến lúc app chạy mới tạch. Quá uy tín!

2. Deep Links dễ như ăn kẹo

Khách bấm vào một cái link kiểu appcuatoi.com/product/123 từ Facebook, anh em muốn nó mở thẳng app lên và chui tọt vào trang Chi tiết sản phẩm số 123? Ngày xưa làm trò này mệt rã rời. Giờ với Nav Graph, anh em chỉ cần gắn thẻ <deepLink app:uri="appcuatoi.com/product/{productId}" /> vào cái Destination Detail trong file XML là xong. Thằng NavController sẽ tự lo liệu việc parse URL và nhét ID vào Safe Args cho anh em xài.

Chốt hạ

Navigation Component thực sự là một cuộc cách mạng của Google nhằm "dọn rác" cho cái kiến trúc Android lổn nhổn ngày xưa. Nó mang cái tư duy quản lý routing rành mạch từ giới làm Web/Backend xuống cho Mobile, giúp anh em dev bớt rụng tóc đi rất nhiều.

Nếu anh em đang maintain dự án cũ thì thôi cứ ráng chịu đựng, nhưng nếu được start một project Android mới, thì bắt buộc phải lôi Navigation Graph vào xài nhé. Không xài là có lỗi với bản thân đấy!

Anh em Android dev dạo này chuyển sang Compose hết chưa hay vẫn lặn ngụp với XML? Để lại comment chém gió cho vui nhé. Vote cho bài để mình có động lực gõ tiếp mấy cái tips hay ho nha!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí