Tổng quan về tác vụ ở chế độ nền

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 người dùng có thể dễ dàng hiểu rõ, chúng tôi phân loại việc này thành 3 loại tác vụ chính: công việc không đồng bộ, công việc trong nềndị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 các 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ộ, công việc trong nền hoặc dịch vụ trên nền trước) của tác vụ đó.

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ó 2 tình huống chính cần cân nhắc đối với công việc ở chế độ nền:

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ư hoạt động trong nền, công việc không đồng bộ 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).

Hoạt động chạy trong nền

Tác vụ trong nền là một lựa chọn linh hoạt hơn khi bạn cần thực hiện tác vụ sẽ 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 cho tác vụ chạy ở chế độ nền là sử dụng WorkManager, mặc dù trong một số trường hợp, bạn có thể sử dụng API JobScheduler của nền tảng này.

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ố trường hợp phổ biến nhất đối với công việc ở chế độ nền là:

  • 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ế:

Tác vụ do người dùng đưa ra yêu cầu

Sơ đồ quy trình cho thấy cách chọn API phù hợp. Biểu đồ này tóm tắt nội dung trong phần "Các thao tác do người dùng yêu cầu".
Hình 1: Cách chọn API phù hợp để chạy tác vụ trong nền do người dùng khởi tạo.

Nếu một ứng dụng cần thực hiện tác vụ trong nền và thao tác đó do người dùng thực hiện trong khi ứng dụng đang 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 hoạt động 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à phải cân nhắc xem trải nghiệm người dùng có bị tổn hại hay không nếu một tác vụ bị trì hoãn hoặc huỷ. 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

Sơ đồ quy trình cho thấy cách chọn API phù hợp. Biểu đồ này tóm tắt nội dung trong phần "Các việc cần làm để ứng phó với một sự kiện".
Hình 2: Cách chọn API phù hợp để chạy tác vụ trong nền do sự kiện kích hoạt.

Đô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ư:

Đâ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ụ mất nhiều thời gian hơn vài giây, hãy sử dụng công việc trong nền.