Bağlı hizmet, istemci-sunucu arayüzündeki sunucudur. Bileşenlerin hizmete bağlanması, istek gönderme, yanıt alma ve performansın işlemler arası iletişim (IPC) Bağlı bir hizmet genellikle yalnızca başka bir kullanıcıya hizmet verirken çalışır uygulama bileşenine sahiptir ve arka planda süresiz olarak çalışmaz.
Bu dokümanda, bağlama ve bağlı hizmet oluşturma hakkında bilgi verilmektedir. diğer uygulama bileşenlerinden hizmete geçiyor. Aşağıdaki hizmetler hakkında daha fazla bilgi edinmek için: Örneğin, bir hizmetten bildirim gönderme ve hizmeti çalışacak şekilde ayarlama ön planda çalışıyorsa, şuraya bakın: Hizmetlere genel bakış.
Temel bilgiler
Bağlı hizmet, Service
sınıfının bir uygulamasıdır ve
diğer uygulamalar da bu modele bağlı kalarak onunla etkileşimde bulunur. Bir
hizmeti için onBind()
geri çağırma yöntemini uygularsınız. Bu
yöntem, kullanılan programlama arayüzünü tanımlayan bir IBinder
nesnesi
kullanabileceği bazı araçlar da
vardır.
Başlatılan bir hizmete bağlan
Hizmetlere genel bakış bölümünde açıklandığı gibi,
hem başlamış hem de bağlı bir hizmet oluşturabilirsiniz. Yani, Arkadaş Bitkiler projesinin
hizmeti başlatan startService()
. Bu çağrı,
süresiz olarak çalışmasını sağlar. Ayrıca, bir istemcinin hizmete bağlanmasını sağlamak için
bindService()
aranıyor.
Hizmetinizin başlatılmasına ve bağlanmasına izin verirseniz hizmet başladığında
Sistem, tüm istemcilerin bağlantısını kaldırdığında hizmeti kaldırmaz.
Bunun yerine
stopSelf()
veya stopService()
numaralı telefonu çağırarak hizmeti açıkça durdurmanız gerekir.
Genellikle onBind()
veya onStartCommand()
, bazen
gerekli olan
uygulayabilirsiniz. Örneğin, bir müzik çalar, verdiği hizmetin çalışması için uygulamayı faydalı bulabilir.
süresiz olarak sağlar ve bağlayıcılığı da sağlar. Bu şekilde, bir etkinlik biraz daha oynayabilmek için
ve kullanıcı uygulamadan ayrılsa bile müzik çalmaya devam eder. Ardından, kullanıcı
uygulamaya döndüğünde ise etkinlik, kontrolün sizde olmasını sağlamak için
oynatmaya devam edebilirsiniz.
Başlatılan bir hizmete bağlama eklerken hizmet yaşam döngüsü hakkında daha fazla bilgi edinmek için Bağlı bir hizmetin yaşam döngüsünü yönetme bölümüne bakın.
İstemci, çağırarak bir hizmete bağlanır
bindService()
Bu durumda,
ServiceConnection
bir uygulama sağlar.
hizmetle olan bağlantıyı izler. Döndürülen değer
bindService()
,
ve istemcinin bu hizmete erişim izni verilip verilmediğini gösterir.
Zaman
Android sistemi, istemci ile hizmet arasında
bağlantı oluşturur.
şunu arar: onServiceConnected()
ServiceConnection
üzerinde. İlgili içeriği oluşturmak için kullanılan
onServiceConnected()
yöntemi bir IBinder
içeriyor
bağımsız değişkeni oluşturur.
Bir hizmete aynı anda birden çok istemci bağlayabilirsiniz. Ancak
sistem, IBinder
hizmeti iletişim kanalını önbelleğe alır.
Başka bir deyişle, sistem, hizmetin onBind()
öğesini çağırır.
yöntemini kullanarak IBinder
özelliğini yalnızca ilk
kullanır. Daha sonra sistem aynı IBinder
öğesini
arama yapmadan aynı hizmete bağlanan tüm ek istemcileri.
tekrar onBind()
.
Son istemcinin hizmet ile olan bağlantısını kestiğinde,
hizmeti startService()
kullanılarak başlatıldı.
Bağlı hizmet uygulamanızın en önemli kısmı,
onBind()
geri çağırma yönteminizin döndürdüğü sonuçlardır. Aşağıdakiler
Bu bölümde, hizmet kalitenizi tanımlamanın
IBinder
arayüzü.
Bağlı hizmet oluştur
Bağlama sağlayan bir hizmet oluştururken IBinder
sağlamanız gerekir
müşterilerin hizmetle etkileşime girmek için kullanabileceği programlama arayüzünü sağlar. Orada
arayüzü üç farklı şekilde tanımlayabilirsiniz:
- Bağlayıcı sınıfını genişletme
- Hizmetiniz kendi uygulamanıza özelse ve aynı süreçte çalışıyorsa
(genellikle
Binder
) uzantısını genişleterek arayüzünüzü oluşturun. sınıf bunun bir örneğini şuradan döndürebilir:onBind()
. Müşteri,Binder
veBinder
uygulamasında bulunan herkese açık yöntemlere doğrudan erişmek için bunu kullanabilir. veyaService
.Hizmetiniz yalnızca kendi şirketiniz için arka plan çalışanıysa tercih ettiğiniz teknik budur. bir uygulamadır. Arayüzünüzü oluşturmak için tercih edilen yöntemin bu olmadığı durumlarda, tek kullanım alanı ve farklı işlemlerde kullanılıp kullanılmadığını gösterir.
- Messenger'ı kullanma
- Arayüzünüzün farklı süreçlerde çalışması gerekiyorsa
Messenger
içeren hizmet arayüzü. Bu şekilde, hizmet farklıMessage
nesne türlerine yanıt veren birHandler
tanımlar.Bu
Handler
daha sonraIBinder
paylaşabilecek birMessenger
için temel oluşturur Böylece istemcininMessage
nesneleri kullanarak hizmete komutlar göndermesini sağlayabilirsiniz. Buna ek olarak, müşteri birMessenger
tanımlayabilir gönderebilir, böylece hizmet iletileri geri gönderebilir.Bu, işlemler arası iletişimi (IPC) gerçekleştirmenin en basit yoludur çünkü
Messenger
tüm istekleri tek bir iş parçacığında sıraya alır ve böylece sizin tasarım yapmanız gerekmez. güvenli olmasını sağlar. - AIDL'yi kullanma
- Android Arayüz Tanımlama Dili (AIDL), nesneleri aşağıdaki parçalara ayırır:
işletim sisteminin anlayabileceği ve bunları işlem süreçlerinde
IPC ile uyumludur.
Messenger
kullanan önceki teknik, aslında olduğunu göreceksiniz.Önceki bölümde belirtildiği gibi,
Messenger
, bir satır öğesi tüm istemci isteklerini tek bir iş parçacığında toplar. Bu nedenle hizmet, istekleri teker teker alır. Eğer, ancak hizmetinizin aynı anda birden fazla isteği işlemesini istiyorsanız AIDL'yi kullanabilirsiniz. doğrudan ekleyebilirsiniz. Bu durumda, hizmetiniz iş parçacığı açısından güvenli ve çoklu iş parçacıkları oluşturabilir.AIDL'yi doğrudan kullanmak için programlama arayüzünü tanımlayan bir
.aidl
dosyası oluşturun. Android SDK araçları, arayüzü uygulayan ve IPC'yi işleyen soyut bir sınıf oluşturmak için bu dosyayı hizmetiniz kapsamında genişletilebilir.
Not: AIDL, çoğu uygulama için en iyi seçenek değildir. bağlı hizmet oluşturabilirsiniz çünkü çoklu iş parçacığı özellikleri ve uygulama daha karmaşık bir hale gelebilir. Dolayısıyla bu belgede hizmetiniz için kullanmak. Bir projeyi tamamlamak için doğrudan AIDL kullanmak için AIDL'ye bakın uygulayacaksınız.
Bağlayıcı sınıfını genişletme
Hizmetinizi yalnızca yerel uygulama kullanıyorsa ve şunu yapması gerekmiyorsa:
farklı süreçlerde
müşterilerinize doğrudan erişim sağlayan kendi Binder
sınıfınızı
hizmette herkese açık yöntemlere erişim.
Not: Bu yalnızca istemci ve hizmet aynıysa çalışır uygulama ve işlem süreçlerine odaklanıyoruz. Örneğin bu, bir müzik türü için müzik çalan kendi hizmetine bir etkinlik bağlamasını gerektiren arka plan.
Bunu nasıl kuracağınız aşağıda açıklanmıştır:
- Hizmetinizde, şunu yapan bir
Binder
örneği oluşturun: şunlardan biri:- İstemcinin çağırabileceği herkese açık yöntemleri içerir.
- Herkese açık yöntemleri olan geçerli
Service
örneğini döndürür: telefon edebilir. - Hizmet tarafından barındırılan ve herkese açık yöntemlere sahip başka bir sınıfın bir örneğini döndürür: telefon edebilir.
onBind()
geri çağırma yönteminden buBinder
örneğini döndürün.- İstemcide,
onServiceConnected()
geri çağırma yöntemindenBinder
değerini alın ve verilen yöntemleri kullanarak bağlı hizmete çağrı yapın.
Not: Hizmet ve istemci aynı olmalıdır istemcinin döndürülen nesneyi yayınlayabilmesi ve API'lerini düzgün bir şekilde çağırabilmesi için uygulamanız gerekir. Hizmet Ayrıca müşteri de aynı süreçte olmalıdır çünkü bu teknik, nasıl işlediğini tartıştık.
Örneğin, müşterilere hizmetteki yöntemlere
Binder
uygulaması:
Kotlin
class LocalService : Service() { // Binder given to clients. private val binder = LocalBinder() // Random number generator. private val mGenerator = Random() /** Method for clients. */ val randomNumber: Int get() = mGenerator.nextInt(100) /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ inner class LocalBinder : Binder() { // Return this instance of LocalService so clients can call public methods. fun getService(): LocalService = this@LocalService } override fun onBind(intent: Intent): IBinder { return binder } }
Java
public class LocalService extends Service { // Binder given to clients. private final IBinder binder = new LocalBinder(); // Random number generator. private final Random mGenerator = new Random(); /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { LocalService getService() { // Return this instance of LocalService so clients can call public methods. return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return binder; } /** Method for clients. */ public int getRandomNumber() { return mGenerator.nextInt(100); } }
LocalBinder
, istemcilerin getService()
LocalService
örneği. Bu, müşterilerin
geliştirmenizi sağlar. Örneğin, müşteriler hizmetten getRandomNumber()
numarasını arayabilir.
İşte LocalService
ile bağlantı kuran ve getRandomNumber()
çağrısı yapan bir etkinlik
bir düğme tıklandığında:
Kotlin
class BindingActivity : Activity() { private lateinit var mService: LocalService private var mBound: Boolean = false /** Defines callbacks for service binding, passed to bindService(). */ private val connection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { // We've bound to LocalService, cast the IBinder and get LocalService instance. val binder = service as LocalService.LocalBinder mService = binder.getService() mBound = true } override fun onServiceDisconnected(arg0: ComponentName) { mBound = false } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) } override fun onStart() { super.onStart() // Bind to LocalService. Intent(this, LocalService::class.java).also { intent -> bindService(intent, connection, Context.BIND_AUTO_CREATE) } } override fun onStop() { super.onStop() unbindService(connection) mBound = false } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute). */ fun onButtonClick(v: View) { if (mBound) { // Call a method from the LocalService. // However, if this call is something that might hang, then put this request // in a separate thread to avoid slowing down the activity performance. val num: Int = mService.randomNumber Toast.makeText(this, "number: $num", Toast.LENGTH_SHORT).show() } } }
Java
public class BindingActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to LocalService. Intent intent = new Intent(this, LocalService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); unbindService(connection); mBound = false; } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute). */ public void onButtonClick(View v) { if (mBound) { // Call a method from the LocalService. // However, if this call is something that might hang, then put this request // in a separate thread to avoid slowing down the activity performance. int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } /** Defines callbacks for service binding, passed to bindService(). */ private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get LocalService instance. LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; }
Yukarıdaki örnek, istemcinin
ServiceConnection
ve onServiceConnected()
geri araması. Sonraki
bölümü, hizmete bu bağlama süreci hakkında daha fazla bilgi sağlar.
Not: Yukarıdaki örnekte,
onStop()
yöntemi, istemci ile hizmet arasındaki bağlantıyı kaldırır.
Ek notlar bölümü.
Daha fazla örnek kod için
LocalService.java
sınıfı ve
ApiDemos'ta LocalServiceActivities.java
sınıfı.
Messenger'ı kullanma
Hizmetinize, uzak işlemlerle iletişim kurmak için ihtiyaç duyuyorsanız
Messenger
, hizmetinize arayüz sağlar. Bu teknik,
AIDL kullanmaya gerek kalmadan işlemler arası iletişim (IPC) gerçekleştiriyorsanız.
Arayüzünüz için Messenger
kullanma
AIDL kullanmaktan daha basittir, çünkü Messenger
çağrışımlar yapılır. Sadece AIDL arayüzü, eş zamanlı istekleri
hizmetini kullanabilirsiniz.
Çoğu uygulamada hizmetin çoklu iş parçacığı işlemesi gerekmez. Dolayısıyla, Messenger
kullanılması hizmetin tek seferde bir çağrıyı işlemesine olanak tanır. Önemliyse
çok iş parçacıklı olmasını istiyorsanız arayüzünüzü tanımlamak için AIDL kullanın.
Aşağıda, Messenger
özelliğinin nasıl kullanılacağıyla ilgili bir özet verilmiştir:
- Hizmet, her biri için geri çağırma alan bir
Handler
uygular araması yapabilirsiniz. - Hizmet,
Messenger
oluşturmak içinHandler
öğesini kullanır nesne (Handler
öğesine referanstır). Messenger
,IBinder
hizmetinonBind()
tarihinden itibaren müşterilere iade ediyor.- İstemciler,
Messenger
örneğini oluşturmak içinIBinder
kullanır. (hizmetinHandler
öğesine referans verir) (hizmetinHandler
öğesini referans alır) HizmeteMessage
nesne eklendi. - Hizmet, her
Message
değeriniHandler
içinde (özellikle dehandleMessage()
yönteminde) alır.
Bu şekilde, istemcinin hizmeti çağırabileceği herhangi bir yöntem olmaz. Bunun yerine
istemci, hizmetinMessage
alır
Handler
değeri.
Aşağıda, Messenger
arayüzü kullanan basit bir örnek hizmet verilmiştir:
Kotlin
/** Command to the service to display a message. */ private const val MSG_SAY_HELLO = 1 class MessengerService : Service() { /** * Target we publish for clients to send messages to IncomingHandler. */ private lateinit var mMessenger: Messenger /** * Handler of incoming messages from clients. */ internal class IncomingHandler( context: Context, private val applicationContext: Context = context.applicationContext ) : Handler() { override fun handleMessage(msg: Message) { when (msg.what) { MSG_SAY_HELLO -> Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show() else -> super.handleMessage(msg) } } } /** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ override fun onBind(intent: Intent): IBinder? { Toast.makeText(applicationContext, "binding", Toast.LENGTH_SHORT).show() mMessenger = Messenger(IncomingHandler(this)) return mMessenger.binder } }
Java
public class MessengerService extends Service { /** * Command to the service to display a message. */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ static class IncomingHandler extends Handler { private Context applicationContext; IncomingHandler(Context context) { applicationContext = context.getApplicationContext(); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } /** * Target we publish for clients to send messages to IncomingHandler. */ Messenger mMessenger; /** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); mMessenger = new Messenger(new IncomingHandler(this)); return mMessenger.getBinder(); } }
Şuradaki handleMessage()
yöntemi:
Handler
, hizmetin gelen Message
verilerini aldığı yerdir
ve what
üyesine bağlı olarak ne yapacağına karar verir.
İstemcinin yapması gereken tek şey, hizmet tarafından döndürülen IBinder
öğesini temel alarak bir Messenger
oluşturmak ve send()
öğesini kullanarak bir ileti göndermektir. Örneğin, aşağıda açıklandığı gibi
MSG_SAY_HELLO
mesajını hizmete gönderir:
Kotlin
class ActivityMessenger : Activity() { /** Messenger for communicating with the service. */ private var mService: Messenger? = null /** Flag indicating whether we have called bind on the service. */ private var bound: Boolean = false /** * Class for interacting with the main interface of the service. */ private val mConnection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService = Messenger(service) bound = true } override fun onServiceDisconnected(className: ComponentName) { // This is called when the connection with the service has been // unexpectedly disconnected—that is, its process crashed. mService = null bound = false } } fun sayHello(v: View) { if (!bound) return // Create and send a message to the service, using a supported 'what' value. val msg: Message = Message.obtain(null, MSG_SAY_HELLO, 0, 0) try { mService?.send(msg) } catch (e: RemoteException) { e.printStackTrace() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) } override fun onStart() { super.onStart() // Bind to the service. Intent(this, MessengerService::class.java).also { intent -> bindService(intent, mConnection, Context.BIND_AUTO_CREATE) } } override fun onStop() { super.onStop() // Unbind from the service. if (bound) { unbindService(mConnection) bound = false } } }
Java
public class ActivityMessenger extends Activity { /** Messenger for communicating with the service. */ Messenger mService = null; /** Flag indicating whether we have called bind on the service. */ boolean bound; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService = new Messenger(service); bound = true; } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected—that is, its process crashed. mService = null; bound = false; } }; public void sayHello(View v) { if (!bound) return; // Create and send a message to the service, using a supported 'what' value. Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to the service. bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service. if (bound) { unbindService(mConnection); bound = false; } } }
Bu örnekte, hizmetin istemciye nasıl yanıt verebileceği gösterilmemektedir.
URL'nin
ve hizmetten geliyorsa istemcide de bir Messenger
oluşturmanız gerekir.
İstemci onServiceConnected()
geri çağırmasını aldığında, aşağıdakileri içeren hizmete bir Message
gönderir:
müşterinin replyTo
parametresindeki Messenger
arasında geçiş yapmak için send()
yöntemini kullanabilirsiniz.
İki yönlü mesajlaşmanın nasıl sağlanacağına ilişkin bir örneği
MessengerService.java
(hizmet) ve
MessengerServiceActivities.java
(istemci) örnekleri.
Bir hizmete bağlan
Uygulama bileşenleri (istemciler) şunu çağırarak bir hizmete bağlanabilir:
bindService()
Android
ardından sistem, hizmetin onBind()
yöntemini çağırır. Bu yöntem etkileşim için IBinder
döndürür.
geri dönelim.
Bağlama eşzamansızdır ve bindService()
, IBinder
değerini şuraya döndürmeden hemen döndürür:
teslim edilir. IBinder
öğesini almak için istemcinin
örneği ServiceConnection
ve bindService()
içine iletilsin. ServiceConnection
,
IBinder
teslim etmek için sistem çağrısı.
Not: Yalnızca etkinlikler, hizmetler ve içerik sağlayıcılar bağlanabilir bir hizmete bağlayamazsınız; yayın alıcıdan bir hizmete bağlayamazsınız.
İstemcinizden bir hizmete bağlamak için aşağıdaki adımları uygulayın:
ServiceConnection
uygulayın.Uygulamanız, iki geri çağırma yöntemini geçersiz kılmalıdır:
onServiceConnected()
- Sistem, tarafından döndürülen
IBinder
öğesini teslim etmek için bu komutu hizmetinonBind()
yöntemi. onServiceDisconnected()
- Hizmetle ilgili bağlantı beklenmedik şekilde olduğunda Android sistemi bu parametreyi çağırır Örneğin, hizmetin çökmesi veya sonlandırılması gibi durumlar. Bu değil istemcinin bağlantısını keser.
bindService()
öğesini çağırarakServiceConnection
uygulamasını iletin.Not: Yöntem false (yanlış) değerini döndürürse istemcinin hizmetle geçerli bir bağlantısı yok. Ancak, şunu arayın:
unbindService()
. gerekir. Aksi takdirde, müşteriniz cihaz boştayken kapanıyor.- Sistem,
onServiceConnected()
geri çağırma yönteminizi çağırdığında şunu kullanarak hizmeti çağırmaya başlayabilirsiniz: arayüz tarafından tanımlanan yöntemler. - Hizmet bağlantısını kesmek için
unbindService()
numaralı telefonu arayın.Uygulamanız istemciyi kaldırdığında istemciniz hâlâ bir hizmete bağlıysa istemcinin bağlantıyı kesmesine neden olur. İşlem tamamlandığında istemcinin bağlantısını kesmek daha iyi bir uygulamadır önemli bir parçasıdır. Bu işlem boşta kalma hizmetinin kapanmasına neden olur. Okuyucu Gelirleri Yöneticisi'ni Ek notlar bölümüne bakın.
Aşağıdaki örnek, istemciyi daha önce
Bağlayıcı sınıfını genişletmeyi gerektirir. Böylece, tek yapması gereken döndürülen
IBinder
öğesini LocalBinder
sınıfına gönderin ve LocalService
örneğini isteyin:
Kotlin
var mService: LocalService val mConnection = object : ServiceConnection { // Called when the connection with the service is established. override fun onServiceConnected(className: ComponentName, service: IBinder) { // Because we have bound to an explicit // service that is running in our own process, we can // cast its IBinder to a concrete class and directly access it. val binder = service as LocalService.LocalBinder mService = binder.getService() mBound = true } // Called when the connection with the service disconnects unexpectedly. override fun onServiceDisconnected(className: ComponentName) { Log.e(TAG, "onServiceDisconnected") mBound = false } }
Java
LocalService mService; private ServiceConnection mConnection = new ServiceConnection() { // Called when the connection with the service is established. public void onServiceConnected(ComponentName className, IBinder service) { // Because we have bound to an explicit // service that is running in our own process, we can // cast its IBinder to a concrete class and directly access it. LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } // Called when the connection with the service disconnects unexpectedly. public void onServiceDisconnected(ComponentName className) { Log.e(TAG, "onServiceDisconnected"); mBound = false; } };
Bu ServiceConnection
ile istemci bir hizmete bağlanabilir
geçmek
aşağıdaki örnekte gösterildiği gibi bindService()
olarak ayarlanır:
Kotlin
Intent(this, LocalService::class.java).also { intent -> bindService(intent, connection, Context.BIND_AUTO_CREATE) }
Java
Intent intent = new Intent(this, LocalService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE);
bindService()
işlevinin ilk parametresi Bağlanacak hizmeti açıkça adlandıranIntent
.Dikkat: Bir
Service
, açıkça bir bağlantı kullanarak uygulamanızın güvenli olduğundan emin olun isteyebilirsiniz. Dolaylı intent kullanarak bir hizmeti başlatmak, hangi hizmetin amaca yanıt verdiğinden emin olamayacağınız için, ve kullanıcı hangi hizmetin başlatıldığını göremez. Android 5.0 (API düzeyi 21) sürümünden itibaren, sistembindService()
öğesini çağırırsanız bir istisna oluşturur gizli bir niyeti vardır.- İkinci parametre,
ServiceConnection
nesnesidir. - Üçüncü parametre, bağlama seçeneklerini gösteren bir işarettir (henüz yapılmamışsa hizmeti oluşturmak için genellikle
BIND_AUTO_CREATE
) yaşanıyor. Diğer olası değerlerBIND_DEBUG_UNBIND
,BIND_NOT_FOREGROUND
veya hiçbiri için0
.
Ek notlar
Bir hizmete bağlama hakkında bazı önemli notları aşağıda bulabilirsiniz:
- Atılan
DeadObjectException
istisnayı her zaman yakala bağlantı kopar. Uzak yöntemler tarafından atılan tek istisna budur. - Nesneler, işlemlerde referans olarak sayılır.
- Genellikle bağlama ve bağlanmayı çözme sırasında
Yukarıda açıklandığı şekilde, müşteri yaşam döngüsünün ortaya çıkan ve yıkıldığı anların
şu örneklere bakabilirsiniz:
- Hizmetle yalnızca etkinliğiniz görünürken etkileşimde bulunmanız gerekiyorsa
onStart()
sırasında bağlanın veonStop()
sırasında bağlantıyı kaldırın. - Etkinliğinizin
arka plan,
onCreate()
sırasında bağlan ve bağlantıyı kes (onDestroy()
sırasında). Bunun, verilerinizin çalışması devam ederken bile arka planda bile hizmeti kullanması gerekir. Bu nedenle hizmet başka bir işlemdeyse sürecin ağırlığını artırırsınız daha yüksek ihtimaller vardır.
Not: Genellikle bağlantıyı bağlayıp etkinliğinizin
onResume()
veonPause()
geri çağırmaları sırasında, bu geri çağırmaların her defasında yaşam döngüsü geçişidir. Bu geçişlerde gerçekleşen işleme sürecini minimumda tutun.Ayrıca, uygulamanızdaki birden fazla etkinlik aynı hizmete bağlı ve bu, belirli bir aradaki geçiş iki tanesi varsa hizmet yok edilebilir ve mevcut haliyle yeniden etkinlik bağlantısını kaldırır (duraklatma sırasında) bir sonraki bağlantı bağlanmadan (devam ettirme sırasında). Bu etkinlik geçişinin yaşam döngülerini koordine eden işlemler Etkinlik yaşam döngüsü bölümünde açıklanmıştır.
- Hizmetle yalnızca etkinliğiniz görünürken etkileşimde bulunmanız gerekiyorsa
Bir hizmete nasıl bağlanılacağını gösteren daha fazla örnek kod için bkz.
ApiDemos'ta RemoteService.java
sınıfı.
Bağlı bir hizmetin yaşam döngüsünü yönetin
Bir hizmetin tüm istemcilerle bağlantısı kaldırıldığında Android sistemi hizmeti kaldırır
(kullanmaya başlamadığınız sürece
startService()
) bilgileri gösterilir.
Bu nedenle hizmetinizin yaşam döngüsünü yönetmeniz
bağlı bir hizmettir. Android sistemi bunu sizin için şunları temel alarak yönetir:
herhangi bir müşteriye bağlı olup olmadığını
görebilirsiniz.
Ancak onStartCommand()
geri çağırma yöntemini uygulamayı seçerseniz hizmeti açıkça durdurmanız gerekir çünkü
hizmeti artık başlatıldı olarak kabul edilir. Bu durumda hizmet,
bağlı olup olmadığına bakılmaksızın, kendisi stopSelf()
ile veya başka bir bileşen stopService()
çağrısıyla duruyor
kullanabilirsiniz.
Ayrıca, hizmetiniz başlatıldı ve bağlamayı kabul ediyorsa sistem
onUnbind()
yönteminizle, isteğe bağlı olarak
Bir istemci hizmete tekrar bağlandığında onRebind()
numaralı telefonu almak istiyorsanız true
. onRebind()
, geçersiz bir yanıt döndürür ancak müşteri, IBinder
ni kendi içinde almaya devam eder.
onServiceConnected()
geri arama.
Aşağıdaki şekilde, bu yaşam döngüsü türünün mantığı gösterilmiştir.
Başlatılan bir hizmetin yaşam döngüsü hakkında daha fazla bilgi edinmek için Hizmetlere genel bakış başlıklı makaleyi inceleyin.