前回はサービスのバインドというものについて眺めただけなので、今回は動かしてみよう。
バインドされたサービスの概要 | 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 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。