2021/05/26

[android] Service (4) - bindしてみよう

前回はサービスのバインドというものについて眺めただけなので、今回は動かしてみよう。

バインドされたサービスの概要  |  Android デベロッパー  |  Android Developers
https://developer.android.com/guide/components/bound-services?hl=ja

サービスを開始させるだけならActivityなどからintentを作ってstartService()すれば動いたのだが、bindするにはいろいろやってやらんといかんようだ。

 

上から順番に。

onBind()を実装してIBinderオブジェクトを返すと、それを通じてServiceに指示ができるようだ。サーバとクライアントの関係だったと思うので、socketみたいなイメージでよいのではなかろうか。

あれ?
今までもデフォルトで作ったサービスにonBind()があったけど、特に何もしていない。

01:     override fun onBind(intent: Intent): IBinder {
02:         Log.d(logTag, "onBind")
03:         TODO("Return the communication channel to the service.")
04:     }

確かに戻り値はIBinderなのだが、これ、戻り値をしていしていないのにコンパイルエラーになってないのだが、どういうことだろうか?

戻り値を指定しない場合はその型のデフォルト値になる、というタイプかと思ったのだが、Stringを返す関数を作ってみたのだが「returnがない」とエラーになった。

コンパイルエラーになっていないのは、コメントと勘違いしていた TODO だった。

TODO - Kotlin Programming Language
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-t-o-d-o.html

常に例外を投げるので、コンパイラもそれより後ろは評価しないと言うことなのだろう。まあ、手っ取り早くサンプルを動かしたいときは役に立つな。
できればwarningくらい出してほしかったが、コンパイラには何も出ない。出す理由がないのか。
AndroidStudioだと色が違って表示されるので、何かKotlinで指定があるのかと思ったが、単に「TODO」という文字列に対して反応しているだけのようだ。


さて、Kotlinの話はここまでにしてbindできるようにしていこう。

 

ActivityなどからbindService()を呼び出せば良いのだが、その引数にIntentとServiceConnectionがいる。IntentはstartService()したものと同じでよさそうな気がするが、ServiceConnectionはなんだろうか?

bindService()を実行した側からすると、

  • bindしようとしているServiceが存在する
  • bindしようとしているServiceに対するアクセスが許可されている

という条件が満たされているかチェックされて、ようやくbindできることになる。

 

bindされるServiceはどうするかというと、bindService()を呼ぶと Serviceの onBind()が呼び出される。 onBind()は IBinderオブジェクトを返して、これを Serviceと通信するのに使ってもらう。
そう書いてあるのだが、bindService()の戻り値はbooleanだ。さっき書いた2条件を満たしたかどうかという戻り値だ。

なので、IBinderオブジェクトは ServiceConnection の方に出てくる。onServiceConnected()の引数で IBinderが渡されてくるのだ。それを getSerivce()するとサービスのインスタンスが取れるようだ。

とはいっても、bindService を呼び出した方と Serviceが同じプロセスであるという保証はないはずだ。だから間に Androidが入って bindService() を経由してうまいこと扱えるようにしてくれているのだろう。

 

はあ、眠たいので今日もここまで。
全然進まない・・・。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。