Tổng quan về tác vụ trong nền

Ứng dụng thường cần làm nhiều việc cùng một lúc. Các API Android cung cấp nhiều cách để bạn thực hiện việc này. Việc chọn đúng phương án là rất quan trọng; một phương án có thể phù hợp với tình huống này nhưng lại hoàn toàn không phù hợp với tình huống khác. Việc chọn sai API có thể ảnh hưởng đến hiệu suất hoặc hiệu quả sử dụng tài nguyên của ứng dụng, từ đó có thể làm hao pin và làm giảm hiệu suất tổng thể của thiết bị 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 đăng trên Cửa hàng Play.

Tài liệu này giải thích các lựa chọn mà bạn có thể sử dụng và giúp bạn chọn lựa 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ụ trong nền có thể được sử dụng theo nhiều cách, mâu thuẫn nhau. Vì vậy, chúng ta cần xác định rõ các thuật ngữ.

Nếu một ứng dụng đang chạy ở chế độ nền, hệ thống sẽ đặt ra một số hạn chế đối với ứng dụng đó. (Ví dụ: trong hầu hết các trường hợp, một ứng dụng ở chế độ nền không thể chạy các dịch vụ 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 thao tác mà ứng dụng đang thực hiện bên ngoài quy trình công việc chính. Để đảm bảo sự thống nhất trong cách hiểu, chúng tôi đã chia thành 3 loại tác vụ chính: công việc không đồng bộ, API lập lịch biểu tác vụ, và dịch vụ nền trước.

Chọn phương án phù hợp

Trong hầu hết các 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 tìm ra danh mục (công việc không đồng bộ, API lập lịch tác vụ hoặc dịch vụ nền trước) mà tác vụ đó thuộc về.

Nếu vẫn chưa chắc chắn, bạn có thể sử dụng lưu đồ mà chúng tôi cung cấp để có thêm thông tin chi tiết giúp bạn đưa ra quyết định. Mỗi lựa chọn này được mô tả chi tiết hơn ở phần sau của tài liệu này.

Có hai trường hợp chính cần xem xét đối với các tác vụ trong nền:

Hai trường hợp này có sơ đồ quyết định riêng.

Công việc không đồng bộ

Trong nhiều trường hợp, ứng dụng chỉ cần thực hiện các thao tác đồng thời khi đang chạy ở nền trước. Ví dụ: một ứng dụng có thể cần thực hiện một phép tính tốn thời gian. Nếu ứng dụng thực hiện phép tính trên luồng giao diện người dùng, thì người dùng sẽ không thể tương tác với ứng dụng cho đến khi phép tính hoàn tất; đ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 lựa chọn phổ biến cho công việc 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ụ nền, công việc không đồng bộ không được đảm bảo sẽ hoàn tất nếu ứng dụng ngừng hoạt động ở 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ập lịch tác vụ

API lập lịch tác vụ là một 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 các 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ể 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 điều kiện để 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ụ chạy lần lượt, chuyển kết quả của tác vụ này sang tác vụ tiếp theo. Để hiểu rõ tất cả các lựa chọn hiện có, hãy đọc danh sách tính năng của WorkManager.

Một số trường hợp 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ỳ
  • 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 một trình 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ụ nền trước cung cấp một cách hiệu quả để chạy ngay các tác vụ không được gián đoạn. Tuy nhiên, dịch vụ nền trước có thể gây tải nặng cho thiết bị và đôi khi ảnh hưởng đến quyền riêng tư và bảo mật. Vì những lý do này, hệ thống đặt ra nhiều hạn chế về cách thức và thời điểm ứng dụng có thể sử dụng dịch vụ nền trước. Ví dụ: người dùng phải nhận thấy được dịch vụ nền trước và trong hầu hết trường hợp, ứng dụng không thể chạy dịch vụ nền trước khi ứng dụng đang chạy trong nền. Để biết thêm thông tin, hãy xem tài liệu về dịch vụ nền trước.

Có hai phương thức để tạo dịch vụ 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ụ đó là một dịch vụ 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ụ nền trước, như đã thảo luận trong phần hỗ trợ cho worker chạy trong thời gian dài. Tuy nhiên, bạn cần biết rằng dịch vụ nền trước do WorkManager tạo phải tuân thủ tất cả các quy định hạn chế giống như mọi dịch vụ nền trước khác. WorkManager chỉ cung cấp một số API tiện lợi để giúp việc tạo dịch vụ nền trước trở nên đơn giản hơn.

API thay thế

Hệ thống cung cấp các API thay thế được thiết kế để hoạt động hiệu quả hơn trong 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, chúng tôi khuyên bạn nên sử dụng API đó thay vì dịch vụ nền trước vì API đó sẽ giúp ứng dụng của bạn hoạt động hiệu quả hơn. Tài liệu về các loại dịch vụ nền trước lưu ý khi có một API thay thế phù hợp để sử dụng thay vì một loại dịch vụ nền trước cụ thể.

Sau đây là một số trường hợp phổ biến nhất khi sử dụng API thay thế:

Việc cần làm do người dùng khởi tạo

Sơ đồ quy trình cho biết cách chọn API phù hợp. Biểu đồ này tóm tắt nội dung trong phần "Tác vụ do người dùng khởi tạo".
Hình 1: Cách chọn API phù hợp để chạy một tác vụ trong nền do người dùng bắt đầ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 này do người dùng bắt đầu trong khi ứng dụng đang hiển thị, hãy trả lời các câu hỏi sau để tìm ra phương pháp phù hợp.

Tác vụ có cần tiếp tục chạy khi ứng dụng đang chạy ở chế độ nền không?

Nếu tác vụ không cần tiếp tục chạy khi ứng dụng ở chế độ nền, bạn nên sử dụng công việc không đồng bộ. Có một số lựa 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 đều ngừng hoạt động nếu ứng dụng chuyển sang chế độ nền. (Các tác vụ này cũng dừ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, 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.

Người dùng có trải nghiệm không tốt nếu tác vụ bị trì hoãn hoặc gián đoạn không?

Bạn cần cân nhắc xem trải nghiệm người dùng có bị ảnh hưởng hay không nếu một tác vụ bị hoãn hoặc huỷ. Ví dụ: nếu một ứng dụng cần cập nhật tài sản, thì người dùng có thể không nhận thấy thao tác này diễn ra ngay lập tức hay vào giữa đêm khi thiết bị đang sạc lại. 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 trong nền.

Đó có phải là một nhiệm vụ ngắn và quan trọng không?

Nếu không thể trì hoãn tác vụ và tác vụ sẽ hoàn tất nhanh chóng, bạn có thể sử dụng dịch vụ nền trước có loại shortService. Những dịch vụ này dễ tạo hơn các dịch vụ 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 chỉ dành cho mục đích này không?

Nếu người dùng có thể thấy tác vụ, thì giải pháp phù hợp có thể là sử dụng dịch vụ nền trước. Các dịch vụ này chạy liên tục sau khi khởi động, vì vậy, đây là lựa chọn phù hợp khi việc 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ụ: một ứ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 nên làm việc này bằng một tuỳ chọn tác vụ nền, vì nếu tác vụ bị tạm dừng, thì quá trình theo dõi sẽ dừng ngay lập tức. Trong trường hợp như vậy, dịch vụ nền trước là hợp lý nhất.

Tuy nhiên, vì dịch vụ nền trước có thể sử dụng nhiều tài nguyên thiết bị, nên hệ thống đặt ra nhiều quy định hạn chế về thời điểm và cách sử dụng các dịch vụ này. Trong nhiều trường hợp, thay vì sử dụng dịch vụ nền trước, bạn có thể dùng một API thay thế để xử lý công việc cho bạn mà ít gặp rắc rối 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 là sử dụng API khoanh vùng địa lý thay vì theo dõi vị trí của người dùng bằng một dịch vụ nền trước.

Việc cần làm để ứng phó với một sự kiện

Sơ đồ quy trình cho biết cách chọn API phù hợp. Biểu đồ này tóm tắt nội dung trong phần "Tác vụ phản hồi sự kiện".
Hình 2: Cách chọn API phù hợp để chạy một tác vụ trong nền được kích hoạt theo sự kiện.

Đôi khi, một ứng dụng cần thực hiện công việc ở 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à một điều kiện kích hoạt bên ngoài (chẳng hạn 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ố thành phần.

Nếu bạn chắc chắn rằng tác vụ sẽ hoàn tất trong 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 các tác vụ đó trong vài giây, ngay cả khi ứng dụng đang chạy trong nền.

Nếu tác vụ mất hơn vài giây, bạn nên bắt đầu một dịch vụ nền trước để xử lý tác vụ đó. Trên thực tế, ngay cả khi ứng dụng của bạn hiện đang ở chế độ nền, ứng dụng vẫn có thể được phép bắt đầu một dịch vụ nền trước, nếu tác vụ đó do người dùng kích hoạt và thuộc một trong các trường hợp miễn trừ được phê duyệt khỏi các quy định hạn chế về việc khởi động ở chế độ nền. 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 khởi động một dịch vụ nền trước ngay cả khi ứng dụng đang chạy ở chế độ nền.

Nếu tác vụ mất nhiều hơn vài giây, hãy sử dụng API lập lịch tác vụ.