Apa yang terjadi jika Layanan Android dimulai beberapa kali?

120

Jika saya memiliki kode berikut:

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

Dalam kode ini DownloadServicemeluas IntentService.

Jadi sekarang ketika saya menelepon startService(intent)apakah itu berarti saya memulai layanan baru setiap kali startService(intent)dipanggil atau apakah itu berarti DownloadServicedijalankan sekali dan kemudian setiap kali saya memanggilnya startService(intent)hanya akan meneruskan maksud yang berbeda dengan startId yang berbeda.

Apakah ini masuk akal, dan yang mana yang merupakan masalahnya?

bytebiscuit.dll
sumber

Jawaban:

167

Layanan hanya akan berjalan dalam satu contoh. Namun, setiap kali Anda memulai layanan, onStartCommand()metode ini dipanggil.

Ini didokumentasikan di sini

Philipp Wendt
sumber
1
Terima kasih. Ia juga mengatakan di sana: "Metode startService () segera kembali dan sistem Android memanggil metode onStartCommand () layanan. Jika layanan belum berjalan, sistem terlebih dahulu memanggil onCreate (), lalu memanggil onStartCommand ()." Jadi jika layanan sudah berjalan maka sistem akan melewati metode onCreate () dan memanggil onStartCommand () saja atau apa?
bytebiscuit
Saya tidak begitu tahu, tetapi saya cukup yakin bahwa itu masalahnya (banyak alasan untuk tidak menelepon onCreate()jika layanan sudah dibuat). Seharusnya mudah untuk menentukan apakah Anda meletakkan a Log.i()di kedua callback dan memeriksa LogCat.
Philipp Wendt
Baru saja melakukan itu ... dan anehnya ia memulai onCreate setelah panggilan startService () terakhir !!!
bytebiscuit
15
Itu karena startService()asynchronous. Jadi saat Anda mengulang panggilan, layanan itu sendiri belum mendapatkan sumber daya apa pun dan belum dimulai.
Philipp Wendt
1
@neelabh tidak "langsung", perlu beberapa saat untuk memulai layanan, dan loop "for" akan tetap berjalan dan memanggil layanan berulang kali, jadi percobaan pertama tidak akan menemukan layanan apa pun yang berjalan ... jadi metode startService () akan dipanggil beberapa kali, hingga startup layanan selesai. Mohon maafkan bahasa Inggris saya yang buruk.
mzalazar
21

Tepat sekali. Hanya satu contoh Layanan yang dibuat untuk proses aplikasi. Dan ketika Anda memanggil StartService();lagi, maka hanya onStartCommand()dipanggil dan Intent baru diteruskan ke onStartCommand()metode.

Catatan: onCreate() tidak dipanggil lagi.

Tentang menelepon bindService()beberapa kali:

Jika Anda memanggil bindService()beberapa kali, hanya satu instance yang digunakan untuk Layanan dan Android Runtime mengembalikan objek IBinder yang sama ke klien.

Artinya, onBind()tidak dipanggil berkali-kali. Dan objek IBinder yang baru saja di-cache dikembalikan.

Anish Mittal
sumber
Apakah onStop()harus dipanggil untuk setiap korespondensi onStartCommand?
IgorGanapolsky
6
@IgorGanapolsky: Pertama-tama, Tidak ada metode callback onStop () seperti itu dalam Layanan. Kita perlu memanggil stopService () atau stopSelf () untuk menghentikan layanan. Dan jika onStartCommand () telah dipanggil beberapa kali untuk beberapa maksud, maka kita hanya perlu memanggil stopSelf () atau stopService () sekali saja. Jika menggunakan IntentService, Anda harus memanggil stopSelfResult (int id) dengan meneruskan id awal permintaan dari onHandleIntent (), yang akan menghentikan permintaan start id terkait, yang ditempatkan dalam antrean kerja IntentService. Semoga ini membantu.
Anish Mittal
8

Menambahkan beberapa informasi lagi ke jawaban di atas yang mungkin berguna bagi orang lain adalah, startIdbahwa onStartCommand()metode yang diterima berbeda untuk setiap startService()panggilan.

Juga jika kita menulis untuk loop seperti yang disebutkan di atas, kode yang ditulis onHandleIntent()akan dieksekusi berkali-kali seperti yang didefinisikan oleh frekuensi loop for, tetapi secara berurutan dan tidak secara paralel.

Konsepnya adalah IntentServicemembuat antrean kerja dan setiap permintaan ke startService()pemicu onStartCommand()yang pada gilirannya menyimpan maksud dalam antrean kerja dan kemudian meneruskan maksud satu per satu ke onHandleIntent().

Rahul Gupta
sumber
2

Menurut dok :

Metode startService () segera kembali, dan sistem Android memanggil metode onStartCommand () layanan. Jika layanan belum berjalan, sistem akan memanggil onCreate () terlebih dahulu, lalu memanggil onStartCommand ().

dan

Beberapa permintaan untuk memulai layanan menghasilkan beberapa panggilan yang sesuai ke onStartCommand () layanan. Namun, hanya satu permintaan untuk menghentikan layanan (dengan stopSelf () atau stopService ()) yang diperlukan untuk menghentikannya.

Amir Rezazadeh
sumber