2021/05/28

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

前回の続きで、Serviceをbindする方の入口となる IBinderの派生クラスを見ているところである。

inner classとして IBinderの派生クラスである LocalService.LocalBinder クラスを作っているのだが、そこで1つだけ実装されている関数が分からん。

01: // Return this instance of LocalService so clients can call public methods
02: fun getService(): LocalService = this@LocalService

関数名は getService。
戻り値の型は LocalService、つまり今回のサンプル実装である Service。
Kotlinでは戻り値しかない関数は括弧を書かずにイコールだけで表現できる。

this@LocalService が気になるのだが、おそらくここで this とだけ書くとどの classの thisなのかわからないので @で指定しているのだろう。どの言語でもそうだけど、記号関係は検索しづらくて大変だ。
ああ、ここだ。 superについても同様だ。

Service は intentを経由?して startService()で起動するので、インスタンスは OSが持っているようなものだろう。だからこの thisも OSが持っていると思われるインスタンスだろう。今回はプロセスが1つしかないのでどっかのメモリを指しているだけと思って良いか。

で、この getService()だが、overrideもなにもついていないので、勝手に作った関数である。これをどうするかというと、Binderのインスタンスを Activityなどに渡してあげて、そのインスタンスを LocalService.LocalBinder にキャストし、そうしてようやく getService()を呼び出してインスタンスを得るのだ。

同じメモリなんだから Binderとか経由せずに Serviceのインスタンスを渡せばいいんじゃないの?という気もするのだが、まあ何か理由があるんだろう。リモートオブジェクトのためのベースクラスらしいので、扱いを共通化するためにそうしているのかもしれん。


図にしたら何か分かるやすくなるかと思ったが、全然だ。

image

今回は現在の Serviceのインスタンスをそのまま渡したが、Binder自体に呼び出したい関数があっても良いし、Serviceが持っている他のクラスのインスタンスを返しても良いらしい。自由だ。同じメモリ空間だから、結局どうでもよいってことなんだろうか。他のクラスについても「サービスでホストされた」というのがよくわからんが、たぶん Serviceが直接呼び出すことができるインスタンスなんだろう。

 

Activityサンプルは、ボタンを押したら LocalServiceの randomNumber()を呼び出している。bind しているかどうかをフラグで持つのは分かるが、排他処理はいらないんだろうか? 乱数取得なんて排他とか気にしなくてよいとは思うのだけど気になるな。

というわけで、今日はここまで。

0 件のコメント:

コメントを投稿

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