●バインドによるサービスへのアクセス


サービス内の関数はstartServiceで常駐サービスとして起動するとonStartCommandの部分を一方的に走らせるぐらいしか アクセスできません。
そこで、バインドという仕組みを使い双方向通信でサービス内の変数や関数にアクセスしたいと思います。
ただし、全ての参照が無くなった時点でサービスは破棄されます、バインドだけではサービスの常駐は望めません

まずは、新たなtest_serviceというクラスを作成してサービスを作成します。
このサービス内のパブリックメソッドおよびパブリック変数にアクセスできるようにしたいと思います。

public class test_service extends android.app.Service
{
    public int i;

    @Override
    public android.os.IBinder onBind(android.content.Intent intent)
    {
        return new test_binder(this);
    }

    public int test(int j){
        i+=j;
        return i;
    }

    @Override
    public void onCreate(){
        //サービスが作成され初期化された時に一度だけ動く部分
    }

    @Override
    public int onStartCommand(android.content.Intent intent, int flags, int startId) {
        //startServiceでサービスを起動させた場合に毎度動く部分
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        //サービスが破棄される時の後始末
    }
}
関数 int test(int) 内では渡された値を合計して返す処理をしています。
次にこのサービス自体を他の部分と結びつけるBinderクラスを作成します。

public class test_binder extends android.os.Binder{
    public test_service _test_service;
    test_binder(test_service service) {
        _test_service=service;
    }
}
このクラスではコンストラクタで渡されたサービスの参照をパブリック変数に保持するようにしています。

作成したBinderクラスを経由してサービスにアクセスしてみます。
アクセスするときにはbindServiceを使うのですが、即座に接続されるわけではありません。
ServiceConnectionのonServiceConnectedをオーバーライトして接続されるまで待ちましょう。

public class MainActivity extends AppCompatActivity {
    android.content.ServiceConnection _ServiceConnection;
    test_service _test_service=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        android.content.Intent _Intent;
        _Intent = new android.content.Intent(this, test_service.class);

        _ServiceConnection = new android.content.ServiceConnection() {
            @Override
            public void onServiceConnected(android.content.ComponentName name, android.os.IBinder binder) {
                _test_service=((test_binder)binder)._test_service;
            }
            @Override
            public void onServiceDisconnected(android.content.ComponentName name) {
            }
        };
        bindService(_Intent, _ServiceConnection, BIND_AUTO_CREATE);

        ((android.widget.Button)findViewById(R.id.button))
                .setOnClickListener(new android.view.View.OnClickListener() {
                    public void onClick(android.view.View view) {
                        if(null!=_test_service) {
                            int i=_test_service.test(1);
                            ((android.widget.Button)view).setText("" + i);
                        }
                    }
                });

    }
    @Override
    protected void onDestroy() {
        unbindService(_ServiceConnection);
        super.onDestroy();
    }
}
画面にボタンを張り付けてクリックするとサービス内の int test(int) メソッドが呼び出されます。
メソッドだけではなくパブリック変数なども読み書き自在です。


▲トップページ > android