จะเกิดอะไรขึ้นหากบริการ Android เริ่มต้นหลายครั้ง


120

หากฉันมีรหัสต่อไปนี้:

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

ในรหัสนี้ขยายDownloadServiceIntentService

ตอนนี้เมื่อฉันโทรไปstartService(intent)นั่นหมายความว่าฉันกำลังเริ่มบริการใหม่ทุกครั้งที่startService(intent)มีการเรียกหรือนั่นหมายความว่าDownloadServiceมีการเรียกใช้ครั้งเดียวแล้วทุกครั้งที่ฉันเรียกstartService(intent)มันก็จะส่งผ่านจุดประสงค์ที่แตกต่างกันด้วย startId ที่แตกต่างกัน

สิ่งนี้สมเหตุสมผลหรือไม่และกรณีใดในกรณีนี้

คำตอบ:


167

บริการจะทำงานในอินสแตนซ์เดียวเท่านั้น อย่างไรก็ตามทุกครั้งที่คุณเริ่มบริการonStartCommand()จะมีการเรียกวิธีนี้

นี่คือเอกสารที่นี่


1
ขอบคุณ นอกจากนี้ยังระบุว่า: "เมธอด startService () จะส่งคืนทันทีและระบบ Android เรียกใช้เมธอด onStartCommand () ของบริการหากยังไม่ได้ทำงานระบบจะเรียก onCreate () ก่อนจากนั้นเรียก onStartCommand ()" ดังนั้นหากบริการทำงานอยู่แล้วระบบจะข้ามเมธอด onCreate () และเรียก onStartCommand () เท่านั้นหรืออะไร?
bytebiscuit

ฉันไม่รู้จริงๆ แต่ฉันค่อนข้างแน่ใจว่าเป็นเช่นนั้น (ทำให้มีเหตุผลมากมายที่จะไม่โทรหาonCreate()หากมีการสร้างบริการแล้ว) ควรง่ายต่อการตรวจสอบว่าคุณใส่Log.i()การเรียกกลับทั้งสองหรือไม่และตรวจสอบ LogCat
Philipp Wendt

เพิ่งทำอย่างนั้น ... และแปลกพอที่จะเริ่มต้น onCreate หลังจากการเรียก startService () ครั้งสุดท้าย !!!
bytebiscuit

15
นั่นเป็นเพราะstartService()เป็นแบบอะซิงโครนัส ดังนั้นในขณะที่คุณกำลังวนสายบริการเองก็ยังไม่ได้รับทรัพยากรใด ๆ และยังไม่เริ่มต้น
Philipp Wendt

1
@neelabh ไม่ใช่ "ทันที" ต้องใช้เวลาพอสมควรในการเริ่มให้บริการและลูป "for" จะยังคงทำงานและเรียกใช้บริการซ้ำแล้วซ้ำอีกดังนั้นการพยายามครั้งแรกจะไม่พบบริการใด ๆ ที่ทำงานอยู่ ... ดังนั้นวิธีการ startService () จะถูกเรียกสองสามครั้งจนกว่าการเริ่มต้นบริการจะเสร็จสมบูรณ์ โปรดขอโทษภาษาอังกฤษที่ไม่ดีของฉัน
mzalazar

21

ถูกต้องแน่นอน มีการสร้างบริการเพียงอินสแตนซ์เดียวสำหรับขั้นตอนการสมัคร และเมื่อคุณโทรStartService();อีกครั้งonStartCommand()จะมีการเรียกเท่านั้นและ Intent ใหม่จะถูกส่งไปยังonStartCommand()เมธอด

หมายเหตุ: onCreate()จะไม่เรียกอีก

เกี่ยวกับการโทรbindService()หลายครั้ง:

เมื่อคุณโทรbindService()หลายครั้งจะมีการใช้อินสแตนซ์เดียวสำหรับบริการอีกครั้งและ Android Runtime จะส่งคืนอ็อบเจ็กต์ IBinder เดียวกันไปยังไคลเอนต์

หมายถึงonBind()ไม่เรียกหลายครั้ง และส่งคืนอ็อบเจ็กต์ IBinder ที่แคชไว้


จะonStop()ต้องถูกเรียกร้องให้สอดคล้องกันทุกคนonStartCommandหรือไม่?
IgorGanapolsky

6
@IgorGanapolsky: ก่อนอื่นไม่มีวิธีการโทรกลับเช่น onStop () ในบริการ เราจำเป็นต้องโทรไปที่ stopService () หรือ stopSelf () เพื่อหยุดบริการ และเมื่อ onStartCommand () ถูกเรียกหลายครั้งสำหรับหลาย Intent เราจำเป็นต้องเรียกใช้เพียง stopSelf () หรือ stopService () เพียงครั้งเดียว หากใช้ IntentService คุณควรเรียกใช้ stopSelfResult (int id) ส่งรหัสเริ่มต้นของคำขอจาก onHandleIntent () ซึ่งจะหยุดการร้องขอรหัสเริ่มต้นที่เกี่ยวข้องซึ่งวางไว้ในคิวงานของ IntentService หวังว่านี่จะช่วยได้
Anish Mittal

8

เพิ่มข้อมูลเพิ่มเติมบางอย่างเพื่อให้คำตอบดังกล่าวข้างต้นซึ่งอาจจะเป็นประโยชน์สำหรับคนอื่น ๆ ก็คือstartIdว่าonStartCommand()วิธีการที่ได้รับแตกต่างกันสำหรับทุกstartService()การโทร

นอกจากนี้ถ้าเราเขียนสำหรับลูปดังที่กล่าวไว้ข้างต้นโค้ดที่เขียนonHandleIntent()จะดำเนินการหลายครั้งตามที่กำหนดโดยความถี่สำหรับลูป แต่เรียงตามลำดับและไม่ขนานกัน

แนวคิดคือIntentServiceสร้างคิวงานและขอให้แต่ละstartService()ทริกเกอร์ซึ่งในร้านค้าเปิดเจตนาในคิวงานแล้วผ่านความตั้งใจหนึ่งโดยหนึ่งonStartCommand()onHandleIntent()


2

ตามเอกสาร :

วิธี startService () จะส่งคืนทันทีและระบบ Android เรียกใช้เมธอด onStartCommand () ของบริการ หากบริการยังไม่ทำงานระบบจะเรียกใช้ onCreate () ก่อนจากนั้นเรียกใช้ onStartCommand ()

และ

คำขอหลายครั้งเพื่อเริ่มบริการส่งผลให้เกิดการเรียกที่เกี่ยวข้องหลายครั้งไปยัง onStartCommand () ของบริการ อย่างไรก็ตามมีเพียงคำขอเดียวที่จะหยุดบริการ (ด้วย stopSelf () หรือ stopService ()) เพื่อหยุดบริการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.