バインドされたサービスの概要

バインドされたサービスは、クライアント サーバー インターフェースにあるサーバーです。コンポーネントは、 たとえば、サービスにバインドするアクティビティ、リクエストの送信、レスポンスの受信、 プロセス間通信(IPC)です。通常、バインドされたサービスは他のアプリ コンポーネントにサービスを提供している間だけ機能し、バックグラウンドで無期限に動作することはありません。

このドキュメントでは、バインドされたサービスの作成方法や、他のアプリ コンポーネントからサービスにバインドする方法について説明します。Google Cloud 上のサービスについて詳しくは、 たとえば、サービスからの通知の配信方法や、サービスの実行を 含まれている場合は、 サービスの概要をご覧ください。

基本情報

バインドされたサービスは、Service クラスの実装で、 他のアプリケーションがそれにバインドし、やり取りします。コンテナ イメージのバインディングを onBind() コールバック メソッドを実装します。このメソッドでは IBinder オブジェクトが返されます。このオブジェクトは、クライアントがサービスとのやり取りに使用できるプログラミング インターフェースを定義します。

開始されたサービスにバインドする

Service の概要で説明したように、 開始されたサービスとバインドされたサービスの両方を作成できますつまり サービスを呼び出して startService() を設定すると、 無期限に実行されますクライアントをサービスにバインドするには、 bindService() を呼び出しています。

サービスの開始とバインドを許可すると、サービスの開始時に すべてのクライアントがバインド解除されても、サービスは破棄されません。 サービスを停止するには、stopSelf() または stopService() を呼び出して明示的に停止する必要があります。

通常、onBind()onStartCommand() のいずれかを実装しますが、両方の実装が必要な場合もあります。たとえば、音楽プレーヤーでサービスを実行させると便利です。 バインドを提供します。これにより、アクティビティはサービスを開始して ユーザーがアプリケーションから離れても音楽は再生され続けます。その後、ユーザーがアプリに戻ると、アクティビティがサービスにバインドして再生の制御を取り戻すことができます。

開始されたサービスにバインドを追加する際のサービスのライフサイクルについて詳しくは、 バインドされたサービスのライフサイクルを管理するをご覧ください。

クライアントがサービスにバインドするには、bindService() を呼び出します。バインド時は、ServiceConnection を実装してサービスとの接続を監視する必要があります。関数の戻り値 bindService() は、 クライアントがそのサービスへのアクセスを許可されているかどうか。

日時 Android システムがクライアントとサービス間の接続を作成し、 onServiceConnected() への電話 ServiceConnection。「 onServiceConnected() メソッドが IBinder を含む クライアントはこの引数を使用して、バインドされたサービスと通信します。

複数のクライアントを 1 つのサービスに同時に接続できます。ただし、システムは IBinder サービス通信チャネルをキャッシュに保存します。つまり、システムはサービスの onBind() を呼び出します。 メソッドを使用し、IBinder が最初に 確認します。その後、onBind() を再度呼び出すことなく、同じサービスにバインドする他のクライアントすべてに同じ IBinder を配信します。

最後のクライアントがサービスからアンバインドされると、サービスが サービスは startService() を使用して開始されました。

バインドされたサービスの実装で最も重要なのは、onBind() コールバック メソッドが返すインターフェースを定義することです。次の セクションでは、サービス リソースを定義する方法を IBinder インターフェース。

バインドされたサービスを作成する

バインドを提供するサービスを作成する際は、IBinder を提供し、クライアントがサービスとのやり取りに使用できるプログラミング インターフェースを提供する必要があります。インターフェースを定義するには、次の 3 つの方法があります。

Binder クラスを拡張する
サービスが独自のアプリケーションに限定され、同じプロセスで実行される場合 としてインターフェースを作成するには、Binder を拡張してインターフェースを作成します。 クラス そこからそのインスタンスを onBind()。クライアントは Binder を受け取り、それを使用して Binder の実装や Service で利用できるパブリック メソッドに直接アクセスできます。

サービスが単にアプリのバックグラウンド ワーカーである場合は、この方法が適しています。この方法が推奨されない唯一のユースケースは、 サービスが他のアプリケーションによって使用される場合や、個別のプロセスにまたがって使用されている場合。

メッセンジャーを使用する
異なるプロセス間で動作するインターフェースが必要な場合は、Messenger を使用してサービスのインターフェースを作成できます。このようにして、サービスは さまざまなタイプの Message オブジェクトに応答する Handler を定義します。

このHandler これは、IBinder を共有できる Messenger の基礎となります。 クライアントが Message オブジェクトを使用してサービスにコマンドを送信できるようにします。さらに、クライアントは次の Messenger を定義できます。 メッセージを返せるようにします。

これは、最も簡単にプロセス間通信(IPC)を行う方法であり、Messenger がすべてのリクエストを 1 つのスレッドにキューイングするため、サービスをスレッドセーフに設計する必要がありません。

AIDL を使用する
Android インターフェース定義言語(AIDL)は、オブジェクトを オペレーティング システムが理解できるプリミティブを作成し、プロセス間で整合させて実行し、 IPC。Messenger を使用する以前の手法は、実際には AIDL に基づいています。 その基礎構造を理解できます。

前のセクションで説明したように、Messenger は、 すべてのクライアント リクエストを 1 つのスレッドで処理するため、サービスはリクエストを一度に 1 つずつ受信します。ただし、サービスで複数のリクエストを同時に処理する場合は、AIDL を直接使用できます。この場合、サービスはスレッドセーフで、マルチスレッド対応である必要があります。

AIDL を直接使用するには、 プログラミング インターフェースを定義する .aidl ファイルを作成します。Android SDK ツールはこのファイルを使用して、インターフェースを実装して IPC を処理する抽象クラスを生成します。その後、それをサービス内で拡張できます。

注: ほとんどのアプリにおいて、AIDL は バインドされたサービスを作成する。これは、マルチスレッド処理機能と、 実装が複雑になる可能性がありますそのため、このドキュメントでは、 サービスに使用できます確実に必要な場合は、 直接使用する方法については、AIDL を参照してください。 ドキュメントをご覧ください

Binder クラスを拡張する

ローカル アプリケーションだけがサービスを使用し、ローカル アプリケーションに プロセス全体にわたり この場合、クライアントに直接的なサービスを提供する独自の Binder クラスを実装できます。 パブリック メソッドへのアクセスを制御するための API です。

注: この方法は、クライアントとサービスが同じアプリとプロセスにある場合(最も一般的なケース)にのみ有効です。たとえば、これは音楽 アプリケーションで音楽を再生する独自のサービスにアクティビティをバインドする必要がある 説明します。

設定手順は次のとおりです。

  1. サービスで、次のいずれかを行う Binder のインスタンスを作成します。
    • クライアントが呼び出せるパブリック メソッドを格納する。
    • クライアントが呼び出せるパブリック メソッドがある、現在の Service インスタンスを返す。
    • クライアントが呼び出せるパブリック メソッドを含む、サービスでホストされた他のクラスのインスタンスを返す。
  2. Binder のインスタンスを onBind() コールバック メソッドから返します。
  3. クライアントで BinderonServiceConnected() コールバック メソッドから受け取り、提供されたメソッドを使用して、バインドされたサービスを呼び出します。

注: クライアントが返されたオブジェクトをキャストし、その API を適切に呼び出すことができるように、サービスとクライアントは同じアプリ内にある必要があります。サービス この手法では何も実行されないため、同じプロセスに存在する必要があります。 プロセス間の整列化が重要になります

Binder の実装を介してサービスのメソッドへのアクセスをクライアントに提供するサービスの例を次に示します。

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

LocalBinderLocalService の現在のインスタンスを取得するための getService() メソッドをクライアントに提供します。これにより、クライアントは あります。たとえば、クライアントはサービスから getRandomNumber() を呼び出せます。

ボタンがクリックされたときに LocalService にバインドして、getRandomNumber() を呼び出すアクティビティの例を次に示します。

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

上記のサンプルは、次の実装を使用してクライアントがサービスにバインドする方法を示しています。 ServiceConnectiononServiceConnected() コールバック。次のセクションでは、サービスへのバインドのプロセスについて詳しく説明します。

注: 上記の例では、 onStop() メソッドは、クライアントをサービスからバインド解除します。 クライアントを適切なタイミングでサービスからバインド解除( その他の情報セクション。

他のサンプルコードについては、ApiDemosLocalService.java クラスと、LocalServiceActivities.java クラスをご覧ください。

メッセンジャーを使用する

リモート プロセスと通信するサービスが必要な場合は、Messenger を使用してサービスのインターフェースを提供できます。この手法により、 AIDL を使用することなくプロセス間通信(IPC)を実行する。

Messenger はサービスに対するすべての呼び出しをキューイングするため、インターフェースに Messenger を使用する方が、AIDL を使用するよりも簡単です。純粋な AIDL インターフェースは、複数のリクエストを マルチスレッド処理を実行する必要があります。

ほとんどのアプリケーションでは、サービスでマルチスレッドを実行する必要はないため、Messenger を使用すると、サービスは一度に 1 つの呼び出しを処理できます。これが重要な場合 実装するには、AIDL を使用してインターフェースを定義します。

Messenger の使用方法の概要は次のとおりです。

  1. サービスが、クライアントからの呼び出しごとにコールバックを受け取る Handler を実装します。
  2. サービスが、Handler を使用して Messenger オブジェクト(Handler への参照)を作成します。
  3. Messenger は、サービスが onBind() からクライアントに返す IBinder を作成します。
  4. クライアントが IBinder を使用して、サービスの Handler を参照する Messenger をインスタンス化します。クライアントはこれを使用して Message オブジェクトをサービスに送信します。
  5. サービスが、その Handler(具体的には handleMessage() メソッド)でそれぞれの Message を受け取ります。

この方法には、クライアントがサービスで呼び出すメソッドはありません。代わりに、クライアントは、サービスがその Handler で受け取るメッセージ(Message オブジェクト)を配信します。

Messenger インターフェースを使用するサービスの簡単な例を次に示します。

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

handleMessage() メソッドの Handler は、サービスが受信 Message を受信する場所です。 what メンバーに基づいて処理方法を決定します。

クライアントで必要な操作は、サービスから返された IBinder に基づいて Messenger を作成し、send() を使用してメッセージを送信することだけです。たとえば、ここにバインドするアクティビティは、 MSG_SAY_HELLO メッセージをサービスに配信します。

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

この例では、サービスがクライアントに応答する方法を示していません。 サービスに応答させるには、クライアントで Messenger も作成する必要があります。クライアントは onServiceConnected() コールバックを受け取ると、send() メソッドの replyTo パラメータにクライアントの Messenger を含めた Message をサービスに送信します。

双方向メッセージを提供する方法の例については、MessengerService.java(サービス)と MessengerServiceActivities.java(クライアント)のサンプルをご覧ください。

サービスにバインドする

アプリ コンポーネント(クライアント)がサービスにバインドする際は、bindService() を呼び出します。Android システムがサービスの onBind() メソッドを呼び出し、そこからサービスとのやり取りに必要な IBinder が返されます。

バインドは非同期的に行われます。bindService()IBinder をクライアントに返すことなく、すぐに戻ります。IBinder を受け取るには、クライアントが ServiceConnection のインスタンスを作成し、それを bindService() に渡す必要があります。ServiceConnection には、システムが IBinder を配信するために呼び出すコールバック メソッドが含まれています。

注: サービスにバインドできるのは、アクティビティ、サービス、コンテンツ プロバイダのみです。ブロードキャスト レシーバからサービスにバインドすることはできません。

クライアントからサービスにバインドする手順は、次のとおりです。

  1. ServiceConnection を実装します。

    実装では次の 2 つのコールバック メソッドをオーバーライドする必要があります。

    onServiceConnected()
    システムがこのメソッドを呼び出して、サービスの onBind() メソッドから返された IBinder を配信します。
    onServiceDisconnected()
    サービスへの接続が予期せず行われた場合、Android システムがこれを呼び出します。 情報が失われることがあります。このメソッドは、クライアントのアンバインドの際には呼び出されません。
  2. bindService() を呼び出して、ServiceConnection の実装を渡します。

    注: このメソッドから false が返された場合、クライアントにはサービスへの有効な接続がありません。ただし、 unbindService() 必要がありますそれ以外の場合、クライアントはサービスを シャットダウンします

  3. システムが onServiceConnected() コールバック メソッドを呼び出すと、インターフェースで定義されたメソッドを使用してサービスへの呼び出しを開始できます。
  4. サービスとの接続を切断するには、unbindService() を呼び出します。

    アプリによってクライアントが破棄されたときに、クライアントが引き続きサービスにバインドされている場合は、この破棄によりクライアントがアンバインドされます。実行が完了したら、すぐにクライアントをバインド解除することをおすすめします。 やり取りできます。これにより、アイドル状態のサービスがシャットダウンされます。詳細情報 バインドとアンバインドの適切なタイミングについて詳しくは、その他の注意事項をご覧ください。

次の例では、以前に作成したサービスにクライアントを接続します。 Binder クラスを拡張しているため、後は返された IBinderLocalBinder クラスに追加し、LocalService インスタンスをリクエストします。

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

この ServiceConnection を使用して、次の例のように、クライアントはそれを bindService() に渡すことでサービスにバインドできます。

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() の最初のパラメータは、バインドするサービス名を明示的に指定する Intent です。

    注意: インテントを使用して Pod へのバインドを Service の場合は、明示的な 使用します。暗黙的インテントを使用してサービスを開始する方法は、 どのサービスがインテントに応答するかが正確にわからないため、 ユーザーはどのサービスが開始するのかわかりません。Android 5.0(API レベル 21)以降では、暗黙的インテントを使用して bindService() を呼び出すと、システムから例外がスローされます。

  • 2 つ目のパラメータは、ServiceConnection オブジェクトです。
  • 3 つ目のパラメータは、バインディングのオプションを示すフラグです。通常は BIND_AUTO_CREATE で、まだ作成されていない場合にサービスを作成します。 あります。 その他の有効な値は BIND_DEBUG_UNBIND です。 BIND_NOT_FOREGROUND、または 0

その他の注意事項

サービスへのバインドに関する重要な注意点は次のとおりです。

  • スローされる DeadObjectException 例外を常にトラップする 接続が切断されたときにだけです。リモート メソッドからスローされる例外はこれのみです。
  • オブジェクトはプロセス間で有効な参照です。
  • 通常は、同期の際にバインディングとバインド解除を クライアントのライフサイクルの、起動と破棄のタイミングを一致させることができます。 次に例を示します。 <ph type="x-smartling-placeholder">
      </ph>
    • アクティビティが表示されている間にだけサービスを操作する必要がある場合は、onStart() でバインドし、onStop() でバインドを解除します。
    • [ バックグラウンド、onCreate() 中のバインド、バインド解除 (onDestroy())ただし、この設定が バックグラウンドであっても、アクティビティは実行中の間はサービスを使用する必要があるため、 サービスが別のプロセスにある場合、プロセスの重みが増し、 システムによって強制終了される可能性が高まります。

    注: 通常はバインドとアンバインドは行いません アクティビティの onResume()onPause() のコールバックの間に呼び出されると、 ライフサイクル移行の最前線に立つことができます。 このような遷移で発生する処理は最小限に抑えてください。

    また アプリケーション内の複数のアクティビティが同じサービスにバインドされていて、 移行 サービスが破棄され、現在のサービス アカウントとして再作成 アクティビティのバインド解除 (一時停止中)次のバインドの前に(再開中)。このアクティビティ移行は、 アクティビティとライフサイクルの調整については、アクティビティのライフサイクルをご覧ください。

サービスにバインドする方法を示すその他のサンプルコードについては、 ApiDemosRemoteService.java クラス。

バインドされたサービスのライフサイクルを管理する

サービスがすべてのクライアントからアンバインドされると、Android システムによってそのサービスが破棄される (Cloud KMS 鍵を使用して startService())。 そのためサービスのライフサイクルを バインドされたサービスです設定内容に基づいて、Android システムがユーザーの代わりに 特定のクライアントにバインドされているかどうかを 確認できます

ただし、onStartCommand() コールバック メソッドを実装する場合は、サービスを明示的に停止する必要があります。これは、 サービスが「開始済み」と見なされます。この場合、クライアントにバインドされているかどうかにかかわらず、サービスが stopSelf() で自ら停止するか、他のコンポーネントが stopService() を呼び出すまで、サービスは動作し続けます。

また、サービスが開始されてバインディングを受け入れると、システムが onUnbind() メソッドを使用すると、必要に応じて true: 次回クライアントがサービスにバインドされたときに onRebind() の呼び出しを受け取る場合に指定します。onRebind() からは void が返されますが、クライアントは onServiceConnected() コールバックで IBinder を受け取ります。次の図は、この種類のライフサイクルのロジックを示しています。

図 1. 開始されたサービスでバインドも許可する場合のサービスのライフサイクル。

開始されたサービスのライフサイクルの詳細については、サービスの概要をご覧ください。