Điều gì xảy ra nếu Dịch vụ Android được khởi động nhiều lần?


119

Nếu tôi có đoạn mã sau:

Intent intent = new Intent(this,DownloadService.class);     
for(int i=0;i<filesArray.length;i++){        
     startService(intent);          
}

Trong mã này DownloadServicemở rộng IntentService.

Vì vậy, bây giờ khi tôi gọi startService(intent)có nghĩa là tôi đang bắt đầu một dịch vụ mới mỗi lần startService(intent)được gọi hoặc điều đó có nghĩa DownloadServicelà được chạy một lần và sau đó mỗi lần tôi gọi startService(intent)nó sẽ chuyển một ý định khác nhau với một startId khác nhau.

Liệu điều này có ý nghĩa, và cái nào trong số này là trường hợp?

Câu trả lời:


166

Dịch vụ sẽ chỉ chạy trong một trường hợp. Tuy nhiên, mỗi khi bạn bắt đầu dịch vụ, onStartCommand()phương thức được gọi.

Điều này được ghi lại ở đây


1
Cảm ơn. Nó cũng cho biết: "Phương thức startService () trả về ngay lập tức và hệ thống Android gọi phương thức onStartCommand () của dịch vụ. Nếu dịch vụ chưa chạy, trước tiên hệ thống sẽ gọi onCreate (), sau đó gọi onStartCommand ()." Vì vậy, nếu dịch vụ đã chạy thì hệ thống sẽ bỏ qua phương thức onCreate () và chỉ gọi onStartCommand () hoặc gì?
bytebcakes

Tôi thực sự không biết, nhưng tôi khá chắc chắn đó là trường hợp (rất nhiều lý do không gọi onCreate()nếu dịch vụ đã được tạo). Sẽ dễ dàng xác định xem bạn có đặt Log.i()cả hai trong số các cuộc gọi lại hay không và kiểm tra LogCat.
Philipp Wendt

Chỉ cần làm điều đó ... và thật kỳ lạ, nó bắt đầu onCreate sau cuộc gọi startService () cuối cùng !!!
bytebcakes

15
Đó là bởi vì startService()không đồng bộ. Vì vậy, trong khi bạn đang lặp lại các cuộc gọi, bản thân dịch vụ đã không nhận được bất kỳ tài nguyên nào và chưa bắt đầu.
Philipp Wendt

1
@neelabh không "ngay lập tức", phải mất một thời gian để bắt đầu dịch vụ và vòng lặp "cho" sẽ vẫn chạy và gọi lại dịch vụ, vì vậy những lần thử đầu tiên sẽ không tìm thấy dịch vụ nào đang chạy ... vì vậy phương thức startService () sẽ được gọi một vài lần, cho đến khi khởi động dịch vụ hoàn tất. Xin thứ lỗi tiếng anh của tôi.
mzalazar

21

Chuẩn xác. Chỉ có một phiên bản Dịch vụ được tạo cho một quy trình ứng dụng. Và khi bạn gọi StartService();lại, sau đó chỉ onStartCommand()được gọi và Ý định mới được truyền cho onStartCommand()phương thức.

Lưu ý: onCreate() không được gọi lại.

Về việc gọi bindService()nhiều lần:

Khi bạn gọi bindService()nhiều lần, sau đó chỉ một trường hợp được sử dụng cho Dịch vụ và Android Runtime trả về cùng một đối tượng IBinder cho máy khách.

Có nghĩa onBind()là , không được gọi nhiều lần. Và chỉ cần lưu trữ đối tượng IBinder được lưu trữ.


onStop()phải được gọi cho mỗi tương ứng onStartCommand?
IgorGanapolsky

6
@IgorGanapolsky: Trước hết, Không có phương thức gọi lại như vậy trênStop () trong Dịch vụ. Chúng ta cần gọi stopService () hoặc stopSelf () để dừng dịch vụ. Và khi onStartCommand () đã được gọi nhiều lần cho nhiều ý định, thì chúng ta chỉ cần gọi stopSelf () hoặc stopService () một lần. Nếu sử dụng IntentService, bạn nên gọi stopSelfResult (int id) chuyển id bắt đầu của yêu cầu từ onHandleIntent (), sẽ dừng yêu cầu id bắt đầu tương ứng, được đặt trong hàng đợi công việc của IntentService. Hi vọng điêu nay co ich.
Anish Găngal

8

Thêm một số thông tin để các câu trả lời ở trên mà có thể hữu ích cho những người khác là, startIdrằng onStartCommand()phương pháp nhận được là khác nhau cho mỗi startService()cuộc gọi.

Ngoài ra, nếu chúng ta viết vào vòng lặp như đã đề cập ở trên, mã được viết onHandleIntent()sẽ thực thi rất nhiều lần như được xác định bởi tần số vòng lặp for, nhưng theo trình tự và không song song.

Khái niệm này là IntentService tạo ra một hàng đợi công việc và mỗi yêu cầu startService()kích hoạt onStartCommand()lần lượt lưu trữ ý định trong hàng đợi công việc và sau đó chuyển từng ý định một onHandleIntent().


2

Theo tài liệu :

Phương thức startService () trả về ngay lập tức và hệ thống Android gọi phương thức onStartCommand () của dịch vụ. Nếu dịch vụ chưa chạy, trước tiên hệ thống sẽ gọi onCreate () và sau đó nó gọi onStartCommand ().

Nhiều yêu cầu để bắt đầu dịch vụ dẫn đến nhiều cuộc gọi tương ứng đến dịch vụ onStartCommand () của dịch vụ. Tuy nhiên, chỉ có một yêu cầu dừng dịch vụ (với stopSelf () hoặc stopService ()) là bắt buộc để dừng dịch vụ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.