Bound Services绑定服务

本文介绍如何创建、绑定和管理服务,包括使用不同技术创建接口、绑定到服务的步骤及服务的生命周期管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication (IPC). A bound service typically lives only while it serves another application component and does not run in the background indefinitely.

This document shows you how to create a bound service, including how to bind to the service from other application components. However, you should also refer to the Servicesdocument for additional information about services in general, such as how to deliver notifications from a service, set the service to run in the foreground, and more.

The Basics


A bound service is an implementation of the Service class that allows other applications to bind to it and interact with it. To provide binding for a service, you must implement the onBind()callback method. This method returns an IBinder object that defines the programming interface that clients can use to interact with the service.

A client can bind to the service by calling bindService(). When it does, it must provide an implementation ofServiceConnection, which monitors the connection with the service. The bindService() method returns immediately without a value, but when the Android system creates the connection between the client and service, it calls onServiceConnected() on the ServiceConnection, to deliver the IBinder that the client can use to communicate with the service.

Multiple clients can connect to the service at once. However, the system calls your service's onBind() method to retrieve theIBinder only when the first client binds. The system then delivers the same IBinder to any additional clients that bind, without calling onBind() again.

When the last client unbinds from the service, the system destroys the service (unless the service was also started bystartService()).

When you implement your bound service, the most important part is defining the interface that your onBind() callback method returns. There are a few different ways you can define your service's IBinder interface and the following section discusses each technique.

Creating a Bound Service


When creating a service that provides binding, you must provide an IBinder that provides the programming interface that clients can use to interact with the service. There are three ways you can define the interface:

Extending the Binder class
If your service is private to your own application and runs in the same process as the client (which is common), you should create your interface by extending the  Binder class and returning an instance of it from  onBind(). The client receives the  Binder and can use it to directly access public methods available in either the  Binder implementation or even the  Service.

This is the preferred technique when your service is merely a background worker for your own application. The only reason you would not create your interface this way is because your service is used by other applications or across separate processes.

Using a Messenger
If you need your interface to work across different processes, you can create an interface for the service with a  Messenger. In this manner, the service defines a  Handler that responds to different types of Message objects. This  Handler is the basis for a  Messenger that can then share an  IBinder with the client, allowing the client to send commands to the service using  Message objects. Additionally, the client can define a  Messenger of its own so the service can send messages back.

This is the simplest way to perform interprocess communication (IPC), because the Messenger queues all requests into a single thread so that you don't have to design your service to be thread-safe.

Using AIDL
AIDL (Android Interface Definition Language) performs all the work to decompose objects into primitives that the operating system can understand and marshall them across processes to perform IPC. The previous technique, using a  Messenger, is actually based on AIDL as its underlying structure. As mentioned above, the  Messenger creates a queue of all the client requests in a single thread, so the service receives requests one at a time. If, however, you want your service to handle multiple requests simultaneously, then you can use AIDL directly. In this case, your service must be capable of multi-threading and be built thread-safe.

To use AIDL directly, you must create an .aidl file that defines the programming interface. The Android SDK tools use this file to generate an abstract class that implements the interface and handles IPC, which you can then extend within your service.

Note: Most applications should not use AIDL to create a bound service, because it may require multithreading capabilities and can result in a more complicated implementation. As such, AIDL is not suitable for most applications and this document does not discuss how to use it for your service. If you're certain that you need to use AIDL directly, see the AIDL document.

Extending the Binder class

If your service is used only by the local application and does not need to work across processes, then you can implement your own Binder class that provides your client direct access to public methods in the service.

Note: This works only if the client and service are in the same application and process, which is most common. For example, this would work well for a music application that needs to bind an activity to its own service that's playing music in the background.

Here's how to set it up:

  1. In your service, create an instance of Binder that either:
    • contains public methods that the client can call
    • returns the current Service instance, which has public methods the client can call
    • or, returns an instance of another class hosted by the service with public methods the client can call
  2. Return this instance of Binder from the onBind() callback method.
  3. In the client, receive the Binder from the onServiceConnected() callback method and make calls to the bound service using the methods provided.

Note: The reason the service and client must be in the same application is so the client can cast the returned object and properly call its APIs. The service and client must also be in the same process, because this technique does not perform any marshalling across processes.

For example, here's a service that provides clients access to methods in the service through a Binderimplementation:

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = 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 mBinder;
    }

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}

The LocalBinder provides the getService() method for clients to retrieve the current instance ofLocalService. This allows clients to call public methods in the service. For example, clients can callgetRandomNumber() from the service.

Here's an activity that binds to LocalService and calls getRandomNumber() when a button is clicked:

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, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            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 were something that might hang, then this request should
            // occur 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 mConnection = 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;
        }
    };
}

The above sample shows how the client binds to the service using an implementation of ServiceConnectionand the onServiceConnected() callback. The next section provides more information about this process of binding to the service.

Note: In the example above, the onStop() method unbinds the client from the service. Clients should unbind from services at appropriate times, as discussed in Additional Notes.

For more sample code, see the LocalService.java class and the LocalServiceActivities.java class inApiDemos.

Using a Messenger

If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.

Here's a summary of how to use a Messenger:

In this way, there are no "methods" for the client to call on the service. Instead, the client delivers "messages" (Message objects) that the service receives in its Handler.

Here's a simple example service that uses a Messenger interface:

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.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * 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();
        return mMessenger.getBinder();
    }
}

Notice that the handleMessage() method in the Handler is where the service receives the incoming Messageand decides what to do, based on the what member.

All that a client needs to do is create a Messenger based on the IBinder returned by the service and send a message using send(). For example, here's a simple activity that binds to the service and delivers theMSG_SAY_HELLO message to the service:

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 mBound;

    /**
     * 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);
            mBound = 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;
            mBound = false;
        }
    };

    public void sayHello(View v) {
        if (!mBound) 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 (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

Notice that this example does not show how the service can respond to the client. If you want the service to respond, then you need to also create a Messenger in the client. Then when the client receives theonServiceConnected() callback, it sends a Message to the service that includes the client's Messenger in thereplyTo parameter of the send() method.

You can see an example of how to provide two-way messaging in the MessengerService.java (service) andMessengerServiceActivities.java (client) samples.

Binding to a Service


Application components (clients) can bind to a service by calling bindService(). The Android system then calls the service's onBind() method, which returns an IBinder for interacting with the service.

The binding is asynchronous. bindService() returns immediately and does not return the IBinder to the client. To receive the IBinder, the client must create an instance of ServiceConnection and pass it tobindService(). The ServiceConnection includes a callback method that the system calls to deliver theIBinder.

Note: Only activities, services, and content providers can bind to a service—you cannot bind to a service from a broadcast receiver.

So, to bind to a service from your client, you must:

  1. Implement ServiceConnection.

    Your implementation must override two callback methods:

    onServiceConnected()
    The system calls this to deliver the  IBinder returned by the service's  onBind() method.
    onServiceDisconnected()
    The Android system calls this when the connection to the service is unexpectedly lost, such as when the service has crashed or has been killed. This is  not called when the client unbinds.
  2. Call bindService(), passing the ServiceConnection implementation.
  3. When the system calls your onServiceConnected() callback method, you can begin making calls to the service, using the methods defined by the interface.
  4. To disconnect from the service, call unbindService().

    If your client is still bound to a service when your app destroys the client, destruction causes the client to unbind. It is better practice to unbind the client as soon as it is done interacting with the service. Doing so allows the idle service to shut down. For more information about appropriate times to bind and unbind, seeAdditional Notes.

For example, the following snippet connects the client to the service created above by extending the Binder class, so all it must do is cast the returned IBinder to the LocalService class and request the LocalServiceinstance:

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;
    }
};

With this ServiceConnection, the client can bind to a service by passing it to bindService(). For example:

Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

Additional notes

Here are some important notes about binding to a service:

  • You should always trap DeadObjectException exceptions, which are thrown when the connection has broken. This is the only exception thrown by remote methods.
  • Objects are reference counted across processes.
  • You should usually pair the binding and unbinding during matching bring-up and tear-down moments of the client's lifecycle. For example:
    • If you only need to interact with the service while your activity is visible, you should bind duringonStart() and unbind during onStop().
    • If you want your activity to receive responses even while it is stopped in the background, then you can bind during onCreate() and unbind during onDestroy(). Beware that this implies that your activity needs to use the service the entire time it's running (even in the background), so if the service is in another process, then you increase the weight of the process and it becomes more likely that the system will kill it.

    Note: You should usually not bind and unbind during your activity's onResume() and onPause(), because these callbacks occur at every lifecycle transition and you should keep the processing that occurs at these transitions to a minimum. Also, if multiple activities in your application bind to the same service and there is a transition between two of those activities, the service may be destroyed and recreated as the current activity unbinds (during pause) before the next one binds (during resume). (This activity transition for how activities coordinate their lifecycles is described in the Activities document.)

For more sample code, showing how to bind to a service, see the RemoteService.java class in ApiDemos.

Managing the Lifecycle of a Bound Service


When a service is unbound from all clients, the Android system destroys it (unless it was also started withonStartCommand()). As such, you don't have to manage the lifecycle of your service if it's purely a bound service—the Android system manages it for you based on whether it is bound to any clients.

However, if you choose to implement the onStartCommand() callback method, then you must explicitly stop the service, because the service is now considered to be started. In this case, the service runs until the service stops itself with stopSelf() or another component calls stopService(), regardless of whether it is bound to any clients.

Additionally, if your service is started and accepts binding, then when the system calls your onUnbind()method, you can optionally return true if you would like to receive a call to onRebind() the next time a client binds to the service. onRebind() returns void, but the client still receives the IBinder in itsonServiceConnected() callback. Below, figure 1 illustrates the logic for this kind of lifecycle.

Figure 1. The lifecycle for a service that is started and also allows binding.

For more information about the lifecycle of a started service, see the Services document.

绑定的服务是在客户端 - 服务器接口的服务器。绑定的服务允许组件(如活动)绑定到该服务,发送请求,接收响应,甚至进行进程间通信(IPC)。同时它还有另一个应用程序组件并不会在后台运行下去一个绑定服务通常只生活。

本文将向您展示如何创建绑定服务,包括如何绑定到其他应用程序组件的服务。但是,你也应该参考服务文档,对一般的服务,比如如何从服务交付通知,设置服务在前台运行,以及更多其他信息。

基础


绑定的服务是一个实现服务类,允许其他应用程序绑定到它,并与它进行交互。为了提供一个服务绑定,则必须实现onBind()回调方法。此方法返回的IBinder对象,定义编程接口,客户端可以使用与服务进行交互。

客户端可以通过调用绑定到服务bindService() 。当它,它必须提供的实现ServiceConnection,负责监测与服务的连接。该bindService()方法立即返回没有价值,但是当Android系统创建客户端和服务之间的连接,它调用onServiceConnected()ServiceConnection,为客户提供的IBinder客户端可以使用的服务进行通信。

多个客户端可以连接到服务一次。但是,系统调用服务的onBind()方法来检索的IBinder当第一个客户端仅绑定。然后,系统会提供相同的IBinder来结合任何额外的客户端,无需调用onBind()一次。

当最后一个客户端从服务解除绑定,系统破坏服务(除非该服务也被启动startService() )。

当你实现你的绑定服务,最重要的部分是定义你的界面onBind()回调方法返回。有几种不同的方法可以定义服务的的IBinder接口和以下部分讨论每种技术。

创建绑定服务


当创建一个提供绑定服务,你必须提供的IBinder ,提供了编程接口,客户端可以用来与服务进行交互。有三种方法可以定义界面:

扩展类粘结剂
如果您的服务是专用于自己的应用程序,并在同一个进程中的客户端(这是常见的)运行时,你应该通过扩展创建界面 粘结剂类,并从返回它的一个实例  onBind() 。客户端接收 活页夹,并可以使用它来 ​​直接访问任何可用的公共方法 宾德 实施甚至 服务

这是当你的服务仅仅是自己的应用程序后台工作的首选技术。唯一的原因,你会不会创建界面这种方式是因为你的服务被其他应用程序或通过单独的进程。

使用信使
如果您需要的接口在不同的流程工作,你可以创建一个服务的界面 使者。以这种方式,该服务定义了一个 处理程序来响应不同类型的 消息对象。该 处理器 是一个基础 使者,然后可以共享 的IBinder 与客户,允许客户使用发送指令到服 ​​务 信息的对象。此外,客户端可以定义 信使自身这样的服务可以将消息发送回。

这是执行进程间通信(IPC)最简单的方法,因为Messenger的队列中的所有请求到一个单一的线程,这样你就不必来设计你的服务是线程安全的。

使用AIDL
AIDL(Android界面定义语言)执行所有工作分解物进入原语操作系统能够理解和马歇尔他们整个进程来执行IPC。以前的技 ​​术,采用了 信使,实际上是基于AIDL作为其基础结构。如上所述,在 信使中创建单个线程的所有客户机请求的队列,因此,服务接收一次请求之一。但是,如果你希望你的服务能够同时处理多个请求,那么你可以直接使用AIDL。在这种情况下,服务必须能够多线程和建立线程安全。

直接使用AIDL,你必须创建一个.aidl定义编程接口文件。在Android SDK工具使用这个文件来生成实现该接口并处理IPC,然后你就可以你的服务中扩展的抽象类。

注意:大多数应用程序不应该使用AIDL创建绑定的服务,因为它可能需要多线程功能,可以导致更复杂的实现。因此,AIDL是不适合大多数的应用程序和本文档不讨论如何使用它为你服务。如果你确信你需要直接使用AIDL,看到AIDL 文件。

扩展类粘结剂

如果您的服务只能由本地应用程序,也不需要工作跨进程,那么你就可以实现自己的活页夹类,提供了对服务的公共方法您的客户端直接访问。

注意:这只有在客户端和服务都在相同的应用程序和过程,这是最常见的。例如,这将为需要的活性绑定到其自己的服务正在播放音乐的背景音乐应用工作得很好。

以下是如何设置它:

  1. 在服务中,创建一个实例粘结剂,要么:
    • 包含公共方法,客户端可以调用
    • 返回当前服务的实例,它具有公共方法的客户端可以调用
    • 或者,返回由服务与公共方法的客户端可以调用托管于其他类的实例
  2. 返回的这个实例粘结剂onBind()回调方法。
  3. 在客户端,接收活页夹onServiceConnected()回调方法,并使用所提供的方法来绑定服务电话。

注意:在服务和客户端必须在同一应用程序的原因是这样的客户机可投返回的对象和正确地调用它的API。服务和客户端也必须是在相同的过程中,由于该技术不跨进程执行任何编组。

例如,下面是为客户提供接触到通过服务方法服务粘结剂实现:

公共  本地服务 延伸 服务 { 
    //活页夹给客户
    私人 最终 的IBinder mBinder =   LocalBinder (); 
    //随机数发生器
    私人 最终 随机mGenerator =  新的 随机(); 

    / ** 
     *用于客户端粘合剂类。因为我们总是知道该服务
     *运行在同一进程作为其客户,我们不需要处理IPC。
     * / 
    公共  LocalBinder  扩展 宾德 { 
        本地服务的getService () { 
            //返回本地服务的这个实例,因此客户可以调用公共方法
            返回 本地服务; 
        } 
    } 

    @覆盖
    公共 的IBinder onBind 意向意图 { 
        返回mBinder ; 
    } 

    / **客户端的方法* / 
    公共 INT getRandomNumber的() { 
      返回mGenerator nextInt 100 ); 
    } 
}

LocalBinder提供的getService()方法,为客户获取的当前实例本地服务。这使得客户端来调用服务的公共方法。例如,客户端可以调用getRandomNumber的()从服务。

下面是结合活动本地服务,并调用getRandomNumber的() 点击一个按钮时:

     
    
     

    
      
        

    

    
      
        
        绑定到 
           
 
    

    
      
        
        从服务解除绑定
        ,如果 mBound  { 
            unbindService mConnection ); 
            mBound =  ; 
        } 
    } 

    / **当单击一个按钮调用(在布局文件中的按钮高度重视
      *这个方法用android:onclick属性)* / 
    公共 无效onButtonClick 查看v  { 
        如果 mBound  { 
            //调用来自本地服务的方法。
            //但是,如果这一呼吁是一些可能会挂起,那么这个请求应该
            //发生在一个单独的线程,以避免放缓该活动的表现。
            INT NUM = MSERVICE getRandomNumber的(); 
            吐司makeText  “数字”  + NUM  吐司LENGTH_SHORT 显示(); 
        } 
    } 

    / **定义为回调服务绑定,传递给bindService( )
        

        
         
                 
            我们势必本地服务,铸就的IBinder并获得本地服务
             

 
        

        
          
 
        
    

上面的示例显示了客户端使用的实现如何绑定到服务 ServiceConnectiononServiceConnected()回调。下一节提供有关绑定到服务这一过程的详细信息。

注:在上面的例子中, 的onStop()方法从服务解除绑定的客户端。客户应服务在适当的时候取消绑定,在讨论 其他注意事项

欲了解更多示例代码,请参见LocalService.java类和LocalServiceActivities.javaApiDemos

使用信使

如果您需要的服务与远程进程进行通信,那么你可以使用一个 使者提供的接口为您服务。这种技术可以让您无需使用AIDL进行进程间通信(IPC)。

下面是如何使用的总结使者

以这种方式,不存在“的方法”为客户端上的服务调用。相反,客户端提供“信息”(信息对象),该服务在其接收处理程序

下面是一个使用一个简单的例子服务Messenger的界面:

公共  MessengerService  扩展 服务 { 
    / **命令到服 ​​务显示一条消息* / 
    静态 最终 INT MSG_SAY_HELLO =  1 ; 

    / ** 
     从*传入消息处理程序 

        
        
          
              
                
                      
                    
                
                    
            
        
    

    
     目标我们发布的客户端发送消息到IncomingHandler。
     * / 
    最后的 使者mMessenger =   信使 IncomingHandler ()); 

    / ** 
     *当绑定到服务,我们返回一个接口,我们的信使
     *将消息发送到了

    
      
          
        
    

注意,handleMessage()函数中的方法 处理程序是其中服务接收传入的消息 ,并决定做什么,基于上什么构件。

所有的客户需要做的是建立一个Messenger的基础上的IBinder服务返回和使用发送邮件发送() 。例如,这里有一个简单的活动结合服务,并提供了MSG_SAY_HELLO消息服务:

公共  ActivityMessenger  延伸 活动 { 
    / **信使与服务进行通信。* / 
    斜挎MSERVICE =  ; 

    / **标志表明我们是否已经呼吁服务绑定。* / 
    布尔mBound ; 

    / ** 
     *与的主界面交互类 

        
           
            这与该服务的连接已被调用时
            //建立,使我们可以利用的对象
            //与服务交互。我们正与通信
            使用信使服务//,所以在这里我们得到一个客户端
            的那//表示从原始的IBinder 
  
 
        

          
            这就是所谓的当与服务的连接已经
            //意外断开-也就是说,它的进程崩溃。
            MSERVICE =  ; 
            mBound =  ; 
        } 
    }; 

    公共 无效的sayHello 查看v  { 
        如果 (!mBound  的回报; 
        //创建并发送消息到服务,使用支持“是什么” 
            
         

           

        
    

    
      
        

    

    
      
        
        绑定到 
  
            
    

    
      
        
        从服务解除绑定
        如果 mBound  { 
            unbindService mConnection 
            mBound =  ; 
        } 
    } 
}

请注意,这个例子没有说明如何服务可以响应客户端。如果你想在服务响应,那么你还需要创建一个信使的客户端。然后,当客户端接收onServiceConnected()回调,它发送一个消息到包含客户端的服务使者的replyTo的参数的send()方法。

你可以看到如何提供一种在双向消息 ​​传送的示例MessengerService.java(服务)和MessengerServiceActivities.java(客户端)的样品。

绑定到一个服务


应用程序组件(客户端)可通过调用绑定到服务 bindService() 。然后,Android系统调用服务的onBind()方法,该方法返回的IBinder与服务交互。

的结合是异步的。bindService()立即返回,并没有在返回的IBinder给客户端。要接收的IBinder,客户端必须创建一个实例ServiceConnection并将其传递给bindService() 。该ServiceConnection包括系统调用来传递一个回调方法的IBinder

注意:只有活动,服务和内容提供商可以绑定到一个服务,你不能绑定到从广播接收机的服务。

因此,从客户端绑定到一个服务,你必须:

  1. 实施ServiceConnection

    你的实现必须重写两个回调方法:

    onServiceConnected()
    该系统调用它来 ​​传递 的IBinder由服务的返回 onBind()方法。
    onServiceDisconnected()
    Android系统调用这个时候到服务的连接意外失去,如当服务崩溃或已被打死。这是 当客户端解除绑定调用。
  2. 调用bindService() ,传递ServiceConnection实施。
  3. 当系统调用你的onServiceConnected()回调方法,你就可以开始打电话到服务,使用该接口定义的方法。
  4. 从服务断开连接,调用unbindService() 

    如果你的客户仍难免,当你的应用程序破坏了客户服务,破坏导致客户端解除绑定。它更好的做法是,只要它完成与服务进行交互解除客户端。这样做可以让闲置的服务关闭。有关适当的时候更多的信息,绑定和取消绑定,请参阅其他注意事项

例如,下面的代码片段客户端连接到由上面创建的服务 扩展粘合剂类,因此,所有必须做的是转换返回 的IBinder本地服务类,并要求本地服务的实例:

本地服务MSERVICE ; 
私人 ServiceConnection mConnection =   ServiceConnection () { 
    //当建立与服务的连接调用
    公共 无效onServiceConnected 组件名的className  的IBinder 服务 { 
        //因为我们已经绑定到一个明确
        的在运行//服务我们自己的过程中,我们可以
        //铸就了它的IBinder到具体的类,并直接访问它。
        LocalBinder 粘结剂=  LocalBinder 服务; 
        MSERVICE = 粘结剂的getService (); 
        mBound =  ; 
    } 

    //调用时与服务的连接断开unexpectedly 
    public  void onServiceDisconnected ( ComponentName className )  { 
        Log . e ( TAG ,  "onServiceDisconnected" ); 
        mBound =  false ; 
    } 
};

与此ServiceConnection,客户端可以通过它传递给绑定到服务bindService() 。例如:

Intent intent =  new  Intent ( this ,  LocalService . class ); 
bindService ( intent , mConnection ,  Context . BIND_AUTO_CREATE );

补充笔记

以下是关于绑定服务的一些重要事项:

  • 你应该总是陷阱DeadObjectException例外,这是当连接已经打破抛出。这是通过远程方法抛出的唯一例外。
  • 对象引用跨进程计数。
  • 通常你应该配对绑定和解除绑定匹配调高客户的生命周期和拆除过程中的瞬间。例如:
    • 如果你只需要与服务进行交互,而你的活动是可见的,你应该在绑定在onStart() ,并在解除绑定的onStop() 
    • 如果你希望你的活动来接收响应即使它是在后台停止了,那么你就可以在绑定的onCreate() ,并在解除绑定的onDestroy() 。要注意的是这意味着你的活动需要使用服务它的运行(即使在背景中)的整个时间,因此,如果该服务是在另一个过程中,则提高该方法的重量和它变得更可能的是,系统将杀了它。

    注意:您通常应该绑定,你的活动的过程中解除onResume()的onPause() ,因为这些回调发生在每一个生命周期的过渡和你应该保持发生在这些过渡到最低限度的处理。另外,如果您的应用程序绑定到同一服务的多个活动,并有其中的两个活动之间的过渡,服务可能成为下一个绑定之前破坏并重新创建作为当前活动的解除绑定(暂停期间)(恢复过程中)。(此为活动如何协调它们的生命周期活动的过渡中描述活动 的文件。)

欲了解更多示例代码,展示如何绑定到服务,请参阅RemoteService.javaApiDemos

管理绑定服务生命周期


当服务是所有客户端绑定,Android系统破坏它(除非它也与启动onStartCommand() )。因此,你不必来管理服务的生命周期,如果它是一个纯粹的绑定服务的Android系统基于它是否绑定到任何客户端管理它。

但是,如果您选择实现onStartCommand()回调方法,那么你必须明确停止服务,因为该服务已经被认为是开始。在这种情况下,服务运行,直到该服务停止本身与stopSelf()或另一组件调用stopService() ,不管它是否被绑定到任何客户端。

此外,如果您的服务已启动,并接受绑定,然后当系统调用你的onUnbind()方法,你可以选择返回 ,如果你想获得一个呼叫onRebind()的下一次客户端绑定到服务。onRebind ()返回void,但客户端仍然收到的IBinder在其 onServiceConnected()回调。下面,图1中示出了用于这种生命周期的逻辑。

图1为已启动,并且还允许绑定一个服务的生命周期。

有关在启动服务的生命周期的更多信息,请参阅服务文档


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值