最終更新:2016-01-19 (火) 17:46:07 (3012d)  

Android/バインドされたサービス
Top / Android / バインドされたサービス

http://developer.android.com/intl/ja/guide/components/bound-services.html

実装

サービス側

クライアント(アクティビティ)側

IBinderの定義方法

Binderクラスを拡張する

サービス側

  • 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 new LocalBinder();
            return mBinder;
        }
    
        /** method for clients */
        public int getRandomNumber() {
          return mGenerator.nextInt(100);
        }
    }
  1. サービスで次のいずれかに該当する Binder のインスタンスを作成
    • クライアントが呼び出せる public メソッドを含んでいる
    • クライアントが呼び出せる public メソッドで現在の Service インスタンスを返す
    • クライアントが呼び出せる public メソッドのあるサービスでホストされた他のクラスのインスタンスを返す
  2. Binder のインスタンスを onBind() コールバック メソッドから返す
  3. クライアントで、Binder を onServiceConnected?() コールバック メソッドから受け取り、提供されたメソッドを使用してバインドされたサービスを呼び出す

クライアント側

  • public class BindingActivity extends Activity {
        LocalService mService;
        boolean mBound = false;
    
        @Override
        protected void onStart() {
            super.onStart();
            // Bind to LocalService
            Intent intent = new Intent(this, LocalService.class);
            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        }
        /** 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();
            }
        }
        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;
            }
        ...

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

AIDLを使用する

  • ほとんどのアプリケーションにおいて、マルチスレッド化が必要な点や、結果的により複雑な実装となってしまうことから、AIDLを使ったバインドされたサービスの作成はお勧めしません。
  • AIDL はほとんどのアプリケーションに適していないため、このドキュメントではサービスでの AIDL の使用方法については取り上げません。
  • どうしても AIDL の直接使用が必要な場合は、「AIDL」のドキュメントをご覧ください。

呼び出し順

boolean Context.bindService(Intent service, ServiceConnection conn, int flags)

  • バインド(bind)という仕組みを使い、ActvitiyとServiceでコネクションを確立する

IBinder Service.onBind(Intent intent)

  • クライアントがサービスと通信するために使用する、インターフェイスIBinderを実装したクラスを返す必要がある
  • 以下のいずれかのを行う Binder のインスタンスを作成します。
    • クライアントが呼び出せる public メソッドを含める
    • クライアントが呼び出せる public メソッドを持つ、現在の Service インスタンスを返す
    • または、クライアントが呼び出せる public メソッドを持つサービスによりホストされた別のクラスのインスタンスを返す

void ServiceConnection.onServiceConnected(ComponentName name, IBinder service)

  • サービスに接続したときに呼び出されるコールバックメソッド
    boundService = ((サービス.バインダ)service),getService();

...

Service.onDestroy

メモ

  • 1つ目のクライアントのバインドの際にのみ、システムはサービスのonBind() メソッドを呼び出してIBinderを取得します
  • その後システムはonBind()を呼び出すことなく、同じIBinderをバインドしたすべてのクライアントに配信します

参考