Tìm hiểu Service trong Android
Bài đăng này đã không được cập nhật trong 8 năm
1. Service
Service là một thành phần rất quan trọng trong ứng dụng Android. Nó đáp ứng các nhu cầu để thực hiện một hoạt động lâu trong một ứng dụng, hoặc nó cung cấp một số chức năng cho các ứng dụng khác.
Service là gì ?
Service là một thành phần đơn giản khởi tạo bởi hệ thống để làm một số tác vụ lâu dài mà không nhất thiết phải phụ thuộc vào tương tác người dùng. Nó có thể độc lập với vòng đời của Activity và có thể chạy ở 1 tiến trình hoàn toàn khác biệt.
Trước khi thảo luận sâu hơn về Service, chúng ta cần hiểu rõ rằng mặc dù Service thường được sử dụng cho các tác vụ chạy ở background và thực hiện trên các tiến trình khác nhau, nhưng Service không hề đại diện cho một Thread hoặc một tiến trình.
Một Service có hai tính năng chính sau :
- Một cơ sở cho ứng dụng để báo cho hệ thống về những việc nó muốn được thực hiện trong background.
- Một cơ sở cho ứng dụng để cung cấp một số chức năng của nó cho các ứng dụng khác sử dụng.
Service và Threads
Có rất nhiều nhầm lẫn giữa Service và Thread. Khi một Service được khai báo, nó không chứa một Thread. Thực tế , theo mặc định nó chạy trực tiếp trên main thread và bất kì công việc nào hoàn thành trong nó có khả năng tác động trực tiếp đến ứng dụng.
Vì vậy, làm thế nào các Service cung cấp một giải pháp đồng thời? Vâng, một Service không chứa một Thread theo mặc định, nhưng nó có thể dễ dàng cấu hình để làm việc với Thread của riêng mình hoặc với nhiều Thread khác nhau.
Bất chấp việc thiếu một Thread dựng sẵn, một Service là một giải pháp tuyệt vời cho vấn đề đồng bộ trong các tình huống nhất định. Những lý do chính để lựa chọn một Service so với các giải pháp đồng bộ khác như AsyncTask hoặc Hamer framework là:
- Một Service có thể độc lập với vòng đời của Activity.
- Một Service thích hợp với các tác vụ chạy lâu dài.
- Service không cần phụ thuộc vaò tương tác người dùng.
- Khi chạy trên các tiến trình khác nhau, Android có thể giuwx cho các service luôn hoạt động khi hệ thống ko cung cấp đủ tài nguyên.
- Một Service có thể tái khởi động để tiếp tục công việc của nó.
Các loại Service
Có 2 loại Service : start và bound.
Một start service được khởi chạy thông qua Context.startService(). Nói chung nó thực hiện chỉ một tác vụ và nó sẽ chạy vô thời hạn cho đến khi tác vụ kết thúc, sau đó nó sẽ tự tắt. Thông thường, nó không trả lại bất kỳ kết quả với giao diện người dùng.
Một bound service được khởi chạy thông qua Context.bindService(), và nó cho phép 2 cách giao tiếp giuwax client và Service. Nó cũng có thể kết nối với nhiều client. Nó tự tắt khi ko có client nào kết nối tới nó.
Để chọn giuwax hai loại service này, Service phải implement một số hàm callback : onStartCommand() để chạy một started service, và onBind() để chạy một bound service. Một Service có thể chọn một trong hai loại kể trên, nhưng nó cũng có thể áp dụng cả hai cùng một lúc mà không gặp bất kỳ vấn đề gì.
Service Implementation
Để sử dụng một Service, extend từ class Service và override các phương thức callback của nó tùy theo loại Service. Như đã nói ở trên, đối với started services thì implement onStartCommand(), còn đối với bound service thì implement onBind(). Trên thực tế, onBind() phải được khai báo trong cả 2 loại Service kể trên, nhưng nó có thể trả về null cho start service.
public class CustomService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Execute your operations
// Service wont be terminated automatically
return Service.START_NOT_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
// Creates a connection with a client
// using a interface implemented on IBinder
return null;
}
}
-
onStartCommand() : khởi chạy bởi Context.startService(), thường gọi từ một Activity. Khi gọi xong, nó sẽ chạy vô hạn cho đến khi bạn dừng nó lại bằng cách gọi stopSelf() hoặc stopService().
-
onBind() : gọi khi một thành phần muốn kết nối tới service. Được gọi trên hệ thống bởi Context.bindService(). Nó trả về một IBinder cung cấp một interface để giao tiếp với client.
Vòng đời của service cũng rất quan trọng. Phương thức onCreate() và onDestroy() nên được implement để khởi tạo và giair phóng các tài nguyên của Service.
Khai báo Service trong Manifest
Service được khai báo trong Manifest với thẻ :
<manifest ... >
...
<application ... >
<service
android:name=".ExampleService"
android:process=":my_process"/>
...
</application>
</manifest>
2.2 Started Service
Để khởi tạo một started service bạn phải gọi phương thức Context.startService(). Intent phải được tạo với Context và Service. Bất kì thông tin hoặc dữ liệu liên quan nào phải được truyền vào Intent này :
Intent serviceIntent = new Intent(this, CustomService.class);
// Pass data to be processed on the Service
Bundle data = new Bundle();
data.putInt("OperationType", 99);
data.putString("DownloadURL", "http://mydownloadurl.com");
serviceIntent.putExtras(data);
// Starting the Service
startService(serviceIntent);
Trong Service của bạn, phương thức bạn cần quan tâm là onStartCommand(). Trong phương thức này bạn sẽ gọi bất kì hoạt động nào muốn thực hiện trong started service. Bạn sẽ dùng Intent để lưu lại thông tin gửi bởi client. startId đại diện cho một ID duy nhất :
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle data = intent.getExtras();
if (data != null) {
int operation = data.getInt(KEY_OPERATION);
// Check what operation to perform and send a msg
if ( operation == OP_DOWNLOAD){
// make a download
}
}
return START_STICKY;
}
onStartCommand() trả về một hằng số kiểu int điều khiển các hành vi như sau :
- Service.START_STICKY : Service được khởi động lại nếu nó bị tắt đi.
- Service.START_NOT_STICKY : Service không được khởi động lại.
- Service.START_REDELIVER_INTENT : Service được khởi động lại sau khi bị crash và Intent sau khi xử lí sẽ được gửi đi.
Nhuư đã đề cập ở trên, một started service cần phải được dừng lại nếu không nói sẽ chạy vô thời hạn. Để thực hiện được điều này ta gọi stopSelf() từ chính Service hoặc goị stopService() từ phía client :
void someOperation() {
// do some long-running operation
// and stop the service when it is done
stopSelf();
}
All rights reserved