START_STICKY dan START_NOT_STICKY

Jawaban:

371

Kedua kode hanya relevan ketika ponsel kehabisan memori dan membunuh layanan sebelum selesai dijalankan. START_STICKYmemberitahu OS untuk membuat ulang layanan setelah memiliki memori yang cukup dan menelepon onStartCommand()lagi dengan niat nol. START_NOT_STICKYmemberitahu OS untuk tidak repot menciptakan layanan lagi. Ada juga kode ketiga START_REDELIVER_INTENTyang memberitahu OS untuk membuat ulang layanan dan mengembalikan maksud yang sama onStartCommand().

Artikel oleh Dianne Hackborn ini menjelaskan latar belakang ini jauh lebih baik daripada dokumentasi resmi.

Sumber: http://android-developers.blogspot.com.au/2010/02/service-api-changes-starting-with.html

Bagian kuncinya di sini adalah kode hasil baru yang dikembalikan oleh fungsi, memberi tahu sistem apa yang harus dilakukan dengan layanan jika prosesnya mati saat sedang berjalan:

START_STICKY pada dasarnya sama dengan perilaku sebelumnya, di mana layanan dibiarkan "dimulai" dan nanti akan dimulai ulang oleh sistem. Satu-satunya perbedaan dari versi platform sebelumnya adalah bahwa jika ia di-restart karena prosesnya mati, onStartCommand () akan dipanggil pada instance layanan selanjutnya dengan null Intent bukannya tidak dipanggil sama sekali. Layanan yang menggunakan mode ini harus selalu memeriksa kasus ini dan menanganinya dengan tepat.

START_NOT_STICKY mengatakan bahwa, setelah kembali dari onStartCreated (), jika proses tersebut dimatikan tanpa ada sisa perintah mulai untuk disampaikan, maka layanan akan dihentikan alih-alih dimulai kembali. Ini jauh lebih masuk akal untuk layanan yang dimaksudkan hanya berjalan saat mengeksekusi perintah yang dikirim kepada mereka. Sebagai contoh, suatu layanan dapat dimulai setiap 15 menit dari alarm ke jajak pendapat beberapa negara jaringan. Jika terbunuh saat melakukan pekerjaan itu, yang terbaik adalah membiarkannya dihentikan dan memulai saat alarm berbunyi.

START_REDELIVER_INTENT seperti START_NOT_STICKY, kecuali jika proses layanannya dimatikan sebelum ia memanggil stopSelf () untuk maksud tertentu, niat itu akan dikirim kembali sampai selesai (kecuali setelah beberapa kali coba lagi masih tidak dapat menyelesaikan, pada titik mana sistem menyerah). Ini berguna untuk layanan yang menerima perintah pekerjaan untuk dilakukan, dan ingin memastikan bahwa mereka akhirnya menyelesaikan pekerjaan untuk setiap perintah yang dikirim.

Frank Leigh
sumber
1
Bagaimana menghindari panggilan ganda ke task handle Mulai (niat, startId); karena onStart () dan onStartCommand akan dipanggil? apakah ini desain yang bagus? @ Frank Leigh
Sazzad Hissain Khan
2
Apa bendera default, jika tidak ditentukan?
IgorGanapolsky
3
Jika Anda mengikuti "return super.onStartCommand (...);" Anda akan melihat bahwa jika versi target SDK Anda kurang dari ECLAIR (API5 = 2.0) secara default START_STICKY_COMPATIBILITY dikembalikan dan dari 2.0 dan di atas START_STICKY dikembalikan.
MikeL
1
Apa yang Anda maksud dengan "tanpa perintah mulai yang tersisa" di START_NOT_STICKY?
Malwinder Singh
3
@ FrankLeigh Saya tidak setuju itu START_REDELIVER_INTENTseperti START_NOT_STICKY. Sebaliknya itu sepertiSTART_STICKY
CopsOnRoad
107

KISS answer

Perbedaan:

START_STICKY

sistem akan mencoba membuat kembali layanan Anda setelah layanannya mati

START_NOT_STICKY

sistem tidak akan mencoba membuat kembali layanan Anda setelah terbunuh


Contoh standar:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}
Oded Breiner
sumber
5
Ini sebenarnya tidak benar dan membingungkan. Ini adalah kesalahan yang mengatakan: "layanan terbunuh" karena orang dapat berpikir bahwa Anda merujuk pada stopSelf atau stopService, sementara Anda jelas merujuk pada proses dibunuh. Jadi sebaiknya Anda menggunakan proses kata dalam jawaban Anda.
Ilya Gazman
Hai, bagaimana saya bisa menguji START_REDELIVER_INTENT. Saya baru saja menguji START_STICKYdan mematikan aplikasi dengan aplikasi terbaru. Kemudian ingat layanan. Tetapi START_REDELIVER_INTENTtidak pernah menelepon lagi. Mengapa?
Asif Mushtaq
@IlyaGazman Saya dengan hormat tidak setuju. Berhenti dan terbunuh adalah dua kata yang sangat berbeda. Jawaban ini menjelaskan masalah dengan benar dengan cara yang sederhana dan langsung.
NoHarmDan
23

Dokumentasi untuk START_STICKYdan START_NOT_STICKYcukup mudah.

START_STICKY:

Jika proses layanan ini terbunuh ketika dimulai (setelah kembali dari onStartCommand(Intent, int, int)), maka biarkan dalam keadaan mulai tetapi jangan mempertahankan maksud yang disampaikan ini. Nanti sistem akan mencoba untuk membuat kembali layanan. Karena sedang dalam kondisi mulai , itu akan menjamin untuk memanggil onStartCommand(Intent, int, int) setelah membuat instance layanan baru, jika tidak ada perintah mulai yang tertunda untuk dikirim ke layanan, itu akan dipanggil dengan objek niat nol, jadi Anda harus berhati-hati untuk memeriksa ini.

Mode ini masuk akal untuk hal-hal yang akan secara eksplisit dimulai dan dihentikan untuk berjalan selama periode waktu yang sewenang-wenang, seperti layanan yang melakukan pemutaran musik latar belakang.

Contoh: Contoh Layanan Lokal

START_NOT_STICKY:

Jika proses layanan ini terbunuh saat dimulai (setelah kembali dari onStartCommand(Intent, int, int)), dan tidak ada maksud awal yang baru untuk mengirimkannya, maka keluarkan layanan dari keadaan awal dan jangan diciptakan kembali sampai panggilan eksplisit di masa depan untuk Context.startService(Intent). Layanan ini tidak akan menerima onStartCommand(Intent, int, int)panggilan dengan nullIntent karena tidak akan dimulai kembali jika tidak ada Inting yang menunggu untuk disampaikan.

Mode ini masuk akal untuk hal-hal yang ingin melakukan beberapa pekerjaan sebagai hasil dari memulai, tetapi dapat dihentikan ketika di bawah tekanan memori dan akan secara eksplisit memulai sendiri lagi nanti untuk melakukan lebih banyak pekerjaan. Contoh dari layanan seperti itu adalah yang melakukan polling untuk data dari server: ia dapat menjadwalkan alarm untuk melakukan polling setiap Nmenit dengan meminta alarm memulai layanannya. Ketika onStartCommand(Intent, int, int)itu dipanggil dari alarm, ia menjadwalkan alarm baru untuk N menit kemudian, dan menumbuhkan utas untuk melakukan networking-nya. Jika prosesnya mati saat melakukan pemeriksaan itu, layanan tidak akan dimulai ulang sampai alarm berbunyi.

Contoh: ServiceStartArguments.java

Marvin Pinto
sumber
tidak beruntung kawan .. saya tidak bisa menghubungkan dokumentasi dengan kata awam. Saya ingin berhubungan dengan skenario waktu nyata. Saya ingin menunjukkan contoh di perangkat. sehingga mereka bisa mengerti dengan lebih mudah.
prago
untuk START_STICKY dan START_NOT_STICKY diStartCommand () akan dieksekusi hanya sekali dan keluar darinya. Saya pergi melalui sampel yang Anda tunjukkan, tetapi keraguan saya adalah berapa kali onStartCommand () akan dieksekusi. jika saya retret START_STICKY dan masih mencoba membuat kembali layanan, apakah layanan akan dijalankan di StartCommand?
prago
apa yang terjadi pada aktivitas ketika layanan dibuat kembali? Apakah aktivitas juga diciptakan kembali?
ransh
Saya kira kita tidak akan pernah tahu
Denny