Các ứng dụng thường cần thực hiện nhiều việc cùng một lúc. Các API của Android cung cấp nhiều cách để giúp bạn thực hiện việc này. Lựa chọn tuỳ chọn phù hợp là rất quan trọng; một tuỳ chọn có thể phù hợp với một trường hợp nhưng lại rất sai trong trường hợp khác. Việc chọn không đúng API có thể ảnh hưởng đến hiệu suất của ứng dụng hoặc hiệu suất của tài nguyên. Điều này có thể làm tiêu hao pin và làm giảm hiệu suất trên toàn bộ thiết bị của người dùng. Trong một số trường hợp, việc chọn sai phương pháp có thể khiến ứng dụng của bạn không được liệt kê trên Cửa hàng Play.
Tài liệu này giải thích các tuỳ chọn có sẵn cho bạn và giúp bạn chọn tuỳ chọn phù hợp với tình huống của mình.
Thuật ngữ
Một số thuật ngữ quan trọng liên quan đến tác vụ ở chế độ nền có thể được dùng theo nhiều cách trái ngược nhau. Vì lý do này, bạn cần phải xác định các điều khoản của chúng tôi.
Nếu một ứng dụng đang chạy ở chế độ nền, hệ thống sẽ đặt một số hạn chế cho ứng dụng đó. (Ví dụ: trong hầu hết các trường hợp, ứng dụng ở chế độ nền không thể chạy dịch vụ trên nền trước.)
Trong tài liệu này, chúng tôi sẽ sử dụng thuật ngữ "tác vụ" để chỉ một hoạt động mà một ứng dụng đang thực hiện bên ngoài quy trình làm việc chính. Để đảm bảo sự phù hợp giữa mọi người, chúng tôi đưa ra 3 loại tác vụ chính: công việc không đồng bộ, API lên lịch tác vụ và dịch vụ trên nền trước.
Chọn tùy chọn phù hợp
Trong hầu hết trường hợp, bạn có thể tìm ra API phù hợp để sử dụng cho tác vụ của mình bằng cách xác định danh mục (công việc không đồng bộ, API lên lịch tác vụ hoặc dịch vụ trên nền trước) thuộc danh mục đó.
Nếu vẫn không chắc chắn, bạn có thể sử dụng lưu đồ mà chúng tôi cung cấp để giúp quyết định có hiệu quả hơn không. Mỗi tuỳ chọn này sẽ được mô tả chi tiết hơn ở phần sau của tài liệu này.
Có hai tình huống chính cần cân nhắc đối với tác vụ trong nền:
- Tác vụ do người dùng thực hiện trong khi ứng dụng đang hiển thị
- Tác vụ được bắt đầu để phản hồi một sự kiện, cả nội bộ lẫn bên ngoài
2 tình huống này có cây quyết định riêng.
Công việc không đồng bộ
Trong nhiều trường hợp, một ứng dụng chỉ cần thực hiện đồng thời các thao tác khi đang chạy ở nền trước. Ví dụ: Một ứng dụng có thể cần phải thực hiện một phép tính tốn nhiều thời gian. Nếu đã thực hiện phép tính trên luồng giao diện người dùng, người dùng sẽ không thể tương tác với ứng dụng cho đến khi quá trình tính toán kết thúc; điều này có thể dẫn đến lỗi ANR. Trong trường hợp như vậy, ứng dụng nên sử dụng tuỳ chọn công việc không đồng bộ.
Các tuỳ chọn phổ biến cho tác vụ không đồng bộ bao gồm coroutine Kotlin và luồng Java; bạn có thể tìm thêm thông tin trong tài liệu về công việc không đồng bộ. Điều quan trọng cần lưu ý là không giống như các API tác vụ trong nền, công việc không đồng bộ sẽ không được đảm bảo hoàn tất nếu ứng dụng ngừng ở một giai đoạn vòng đời hợp lệ (ví dụ: nếu ứng dụng rời khỏi nền trước).
API lên lịch tác vụ
API lên lịch tác vụ là lựa chọn linh hoạt hơn khi bạn cần thực hiện các tác vụ cần tiếp tục ngay cả khi người dùng rời khỏi ứng dụng. Trong hầu hết trường hợp, lựa chọn tốt nhất để chạy tác vụ trong nền là sử dụng WorkManager, mặc dù trong một số trường hợp, bạn nên sử dụng API JobScheduler
của nền tảng.
WorkManager là một thư viện mạnh mẽ cho phép bạn thiết lập các công việc đơn giản hoặc phức tạp theo nhu cầu. Bạn có thể sử dụng WorkManager để lên lịch cho các tác vụ chạy vào những thời điểm cụ thể hoặc chỉ định các điều kiện cho thời điểm chạy tác vụ. Bạn thậm chí có thể thiết lập chuỗi tác vụ để mỗi tác vụ sẽ chạy lần lượt và chuyển kết quả của tác vụ đó sang tác vụ tiếp theo. Để tìm hiểu tất cả các tuỳ chọn có sẵn, hãy đọc qua danh sách tính năng WorkManager.
Một số tình huống phổ biến nhất đối với tác vụ trong nền bao gồm:
- Tìm nạp dữ liệu từ máy chủ theo định kỳ
- Đang tìm nạp dữ liệu cảm biến (ví dụ: dữ liệu bộ đếm bước)
- Nhận dữ liệu vị trí định kỳ (bạn phải được cấp quyền
ACCESS_BACKGROUND_LOCATION
trên Android 10 trở lên) - Tải nội dung lên dựa trên điều kiện kích hoạt nội dung, chẳng hạn như ảnh do máy ảnh tạo
Dịch vụ trên nền trước
Dịch vụ trên nền trước mang đến một cách hiệu quả để chạy các tác vụ ngay lập tức mà không bị gián đoạn. Tuy nhiên, các dịch vụ trên nền trước có thể gây quá tải cho thiết bị và đôi khi còn kéo theo những hệ luỵ về quyền riêng tư và bảo mật. Vì những lý do này, hệ thống đặt ra rất nhiều hạn chế về cách thức và thời điểm ứng dụng có thể dùng dịch vụ trên nền trước. Ví dụ: người dùng phải nhận thấy được dịch vụ trên nền trước. Trong hầu hết trường hợp, ứng dụng không thể chạy dịch vụ trên nền trước khi ứng dụng chạy trong nền. Để biết thêm thông tin, hãy xem tài liệu về dịch vụ trên nền trước.
Có 2 phương thức để tạo dịch vụ trên nền trước. Bạn có thể khai báo Service
của riêng mình và chỉ định rằng dịch vụ này là dịch vụ trên nền trước bằng cách gọi Service.startForeground()
. Ngoài ra, bạn có thể sử dụng WorkManager để tạo dịch vụ trên nền trước, như đã thảo luận trong bài viết hỗ trợ trình thực thi chạy trong thời gian dài.
Tuy nhiên, quan trọng cần biết là dịch vụ trên nền trước do WorkManager tạo phải tuân thủ tất cả các hạn chế tương tự như mọi dịch vụ trên nền trước khác.
WorkManager chỉ cung cấp một số API tiện lợi để giúp bạn tạo dịch vụ trên nền trước đơn giản hơn.
API thay thế
Hệ thống này cung cấp các API thay thế được thiết kế để hoạt động hiệu quả hơn cho các trường hợp sử dụng cụ thể hơn. Nếu có một API thay thế cho trường hợp sử dụng của bạn, bạn nên sử dụng API đó thay vì dịch vụ trên nền trước vì điều này sẽ giúp ứng dụng của bạn hoạt động tốt hơn. Tài liệu về các loại dịch vụ trên nền trước sẽ ghi chú khi có API thay thế phù hợp để sử dụng thay vì một kiểu dịch vụ cụ thể trên nền trước.
Sau đây là một số trường hợp phổ biến nhất về việc sử dụng API thay thế:
- Sử dụng hoạt động chuyển dữ liệu do người dùng yêu cầu để tải xuống hoặc tải lên với kích thước lớn, thay vì tạo một dịch vụ trên nền trước để đồng bộ hoá dữ liệu
- Sử dụng trình quản lý thiết bị đồng hành để ghép nối Bluetooth và chuyển dữ liệu, thay vì sử dụng dịch vụ trên nền trước của thiết bị đã kết nối
- Sử dụng chế độ hình trong hình để phát video, thay vì tạo dịch vụ trên nền trước khi phát nội dung nghe nhìn
Tác vụ do người dùng đưa ra yêu cầu
Nếu một ứng dụng cần thực hiện các tác vụ trong nền và thao tác đó do người dùng thực hiện trong khi ứng dụng hiển thị, hãy trả lời các câu hỏi này để tìm ra phương pháp phù hợp.
Tác vụ có cần tiếp tục chạy trong khi ứng dụng chạy ở chế độ nền không?
Nếu tác vụ không cần tiếp tục chạy trong khi ứng dụng chạy ở chế độ nền thì bạn nên sử dụng công việc không đồng bộ. Có một số tuỳ chọn để thực hiện công việc không đồng bộ. Điều quan trọng cần hiểu là tất cả các tuỳ chọn này sẽ ngừng hoạt động nếu ứng dụng chuyển sang chạy ở chế độ nền. (Các cảnh báo này cũng sẽ ngừng nếu ứng dụng bị tắt.) Ví dụ: một ứng dụng mạng xã hội có thể muốn làm mới nguồn cấp nội dung của ứng dụng đó, nhưng không cần hoàn tất thao tác nếu người dùng rời khỏi màn hình.
Liệu người dùng có gặp phải trải nghiệm không tốt nếu tác vụ bị trì hoãn hoặc bị gián đoạn không?
Điều quan trọng là bạn phải cân nhắc xem trải nghiệm người dùng có bị tổn hại nếu một tác vụ bị hoãn hoặc huỷ hay không. Ví dụ: nếu một ứng dụng cần cập nhật các thành phần, thì người dùng có thể không nhận thấy liệu thao tác sẽ diễn ra ngay lập tức hay vào giữa đêm khi thiết bị đang sạc. Trong những trường hợp như vậy, bạn nên sử dụng các tuỳ chọn công việc ở chế độ nền.
Đó có phải là một nhiệm vụ ngắn và quan trọng không?
Nếu tác vụ không thể bị trì hoãn và nó sẽ hoàn thành nhanh chóng, bạn có thể sử dụng dịch vụ trên nền trước thuộc loại shortService
. Các dịch vụ này dễ tạo hơn so với các dịch vụ trên nền trước khác và không yêu cầu nhiều quyền. Tuy nhiên, các dịch vụ ngắn phải hoàn tất trong vòng 3 phút.
Có API thay thế nào dành riêng cho mục đích này không?
Nếu người dùng không nhìn thấy tác vụ, thì giải pháp phù hợp có thể là sử dụng dịch vụ trên nền trước. Các dịch vụ này chạy liên tục sau khi bắt đầu nên sẽ là lựa chọn phù hợp khi làm gián đoạn tác vụ sẽ mang lại trải nghiệm không tốt cho người dùng. Ví dụ: ứng dụng theo dõi bài tập thể dục có thể sử dụng cảm biến vị trí để cho phép người dùng ghi lại tuyến đường chạy bộ của họ trên bản đồ. Bạn không muốn thực hiện việc này với tuỳ chọn công việc trong nền, vì nếu tác vụ bị tạm dừng, quá trình theo dõi sẽ dừng lại ngay lập tức. Trong trường hợp như vậy, dịch vụ trên nền trước là phù hợp nhất.
Tuy nhiên, vì các dịch vụ trên nền trước có thể sử dụng nhiều tài nguyên thiết bị, nên hệ thống sẽ đặt nhiều hạn chế về thời điểm và cách thức sử dụng các tài nguyên đó. Trong nhiều trường hợp, thay vì sử dụng dịch vụ trên nền trước, bạn có thể dùng API thay thế để xử lý công việc đó cho bạn mà ít gặp phải sự cố hơn. Ví dụ: nếu ứng dụng của bạn cần thực hiện một hành động khi người dùng đến một vị trí nhất định, thì lựa chọn tốt nhất cho bạn là sử dụng API địa lý thay vì theo dõi vị trí của người dùng bằng dịch vụ trên nền trước.
Việc cần làm để phản hồi một sự kiện
Đôi khi, một ứng dụng cần hoạt động ở chế độ nền để phản hồi một điều kiện kích hoạt, chẳng hạn như:
- Phát đi thông báo
- Thông báo qua Giải pháp gửi thông báo qua đám mây của Firebase (FCM)
- Chuông báo do ứng dụng đặt
Đây có thể là điều kiện kích hoạt bên ngoài (như thông báo FCM) hoặc có thể là để phản hồi chuông báo do chính ứng dụng đặt. Ví dụ: một trò chơi có thể nhận được thông báo FCM yêu cầu cập nhật một số tài sản.
Nếu bạn có thể chắc chắn rằng tác vụ sẽ hoàn tất sau vài giây, hãy sử dụng công việc không đồng bộ để thực hiện tác vụ đó. Hệ thống sẽ cho phép ứng dụng của bạn thực hiện bất kỳ tác vụ nào như vậy vài giây, ngay cả khi ứng dụng đang ở chế độ nền.
Nếu tác vụ mất nhiều thời gian hơn vài giây, thì bạn nên bắt đầu dịch vụ trên nền trước để xử lý tác vụ đó. Trên thực tế, ngay cả khi ứng dụng đang chạy ở chế độ nền, ứng dụng vẫn có thể được phép bắt đầu dịch vụ trên nền trước, nếu tác vụ đó do người dùng kích hoạt và thuộc một trong những trường hợp miễn trừ khỏi các hạn chế khi bắt đầu ở chế độ nền được phê duyệt. Ví dụ: nếu một ứng dụng nhận được thông báo FCM có mức độ ưu tiên cao, thì ứng dụng đó được phép bắt đầu một dịch vụ trên nền trước ngay cả khi ứng dụng đang chạy trong nền.
Nếu tác vụ sẽ mất nhiều thời gian hơn vài giây, hãy sử dụng API lên lịch tác vụ.