https://developer.android.com/reference/android/app/Service#developer-guides

Hầu hết sự nhầm lẫn về lớp Dịch vụ thực sự xoay quanh những gì không phải là:

Do đó, bản thân Dịch vụ thực sự rất đơn giản, cung cấp hai tính năng chính:

Khi một thành phần Service thực sự được tạo ra, cho bất kỳ lý do nào của hai lý do trên, mọi thứ mà hệ thống thực sự làm là khởi tạo thành phần và gọi phương thức onCreate() và bất kỳ callback phù hợp nào khác trên luồng chính. Đến lượt của Service để thực hiện chúng với hành vi phù hợp, như tạo một luồng phụ trong đó nó thực hiện công việc của mình.

Lưu ý rằng vì Service chính nó rất đơn giản, bạn có thể làm cho tương tác của mình với nó càng đơn giản hoặc phức tạp tùy thích: từ xem xử lý nó như một đối tượng Java cục bộ mà bạn gọi phương thức trực tiếp (như minh họa trong Mẫu Dịch vụ Địa phương), đến cung cấp một giao diện có thể từ xa hoàn chỉnh bằng cách sử dụng AIDL.

Service Lifecycle

Có hai lý do mà một dịch vụ có thể được chạy bởi hệ thống. Nếu ai đó gọi Context.startService(), thì hệ thống sẽ lấy dịch vụ (tạo nó và gọi phương thức onCreate() nếu cần) và sau đó gọi phương thức onStartCommand(Intent, int, int) của nó với các đối số được cung cấp bởi client. Tại điểm này, dịch vụ sẽ tiếp tục chạy cho đến khi Context.stopService() hoặc stopSelf() được gọi. Lưu ý rằng nhiều lần gọi Context.startService() không lồng nhau (mặc dù chúng dẫn đến nhiều cuộc gọi tương ứng đến onStartCommand()), vì vậy không có vấn đề gì khi được bắt đầu một dịch vụ sẽ được dừng khi Context.stopService() hoặc stopSelf() được gọi; tuy nhiên, dịch vụ có thể sử dụng phương thức stopSelf(int) của họ để đảm bảo rằng dịch vụ không bị dừng cho đến khi các intent đã được xử lý.

Đối với các dịch vụ được bắt đầu, có hai chế độ hoạt động chính bổ sung mà chúng có thể quyết định chạy trong đó, tùy thuộc vào giá trị chúng trả về từ onStartCommand(): START_STICKY được sử dụng cho các dịch vụ được bắt đầu và dừng theo nhu cầu, trong khi START_NOT_STICKY hoặc START_REDELIVER_INTENT được sử dụng cho các dịch vụ mà chỉ nên tiếp tục chạy trong khi xử lý bất kỳ lệnh nào được gửi đến chúng. Xem tài liệu liên kết để biết thêm chi tiết về ngữ nghĩa.

Client cũng có thể sử dụng Context.bindService() để nhận một kết nối lâu dài đến một dịch vụ. Điều này cũng tạo ra dịch vụ nếu nó chưa chạy (gọi onCreate() trong khi làm điều đó), nhưng không gọi onStartCommand(). Client sẽ nhận được đối tượng IBinder mà dịch vụ trả về từ phương thức onBind(Intent) của nó, cho phép client sau đó gọi lại dịch vụ. Dịch vụ sẽ tiếp tục chạy miễn là kết nối được thiết lập (dù client có giữ tham chiếu đến IBinder của dịch vụ hay không). Thông thường, IBinder được trả về là cho một giao diện phức tạp đã được viết trong aidl.

Một dịch vụ có thể được bắt đầu và có kết nối được liên kết với nó. Trong trường hợp như vậy, hệ thống sẽ giữ dịch vụ chạy miễn là nó được bắt đầu hoặc có một hoặc nhiều kết nối với nó với cờ Context.BIND_AUTO_CREATE. Một khi không còn tình huống nào giữ lại, phương thức onDestroy() của dịch vụ được gọi và dịch vụ được chấm dứt một cách hiệu quả. Tất cả công việc dọn dẹp (dừng luồng, hủy đăng ký các receiver) nên được hoàn thành sau khi trở về từ onDestroy().

Constants

START_CONTINUATION_MASK

Các bit được trả về bởi phương thức onStartCommand(Intent, int, int) mô tả cách tiếp tục dịch vụ nếu nó bị kết thúc. Có thể là START_STICKY, START_NOT_STICKY, START_REDELIVER_INTENT hoặc START_STICKY_COMPATIBILITY.

START_FLAG_REDELIVERY

Cờ này được thiết lập trong phương thức onStartCommand(Intent, int, int) nếu Intent là một phiên gửi lại của một intent đã được gửi trước đó, vì dịch vụ trước đó đã trả về START_REDELIVER_INTENT nhưng đã bị kết thúc trước khi gọi stopSelf(int) cho Intent đó.

START_FLAG_RETRY