2021/05/27

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

なかなか進まないAndroidのServiceだが、技術日記だからのんびりいきます。

前回は、bindService()を呼べば良いけど、その前に ServiceConnectionなんかがいるということがわかるところまでだった。

 

bindしてもらう Serviceは、ただ onBind()を実装して IBinderを返せばよいというわけではなく、クライアントからの要求を受け付けられるようにしないといけない。インターフェースを提供する、と表現されているので、それに倣おう。

インターフェースの定義には3つの方法がある。

  • Binderクラスの拡張
  • Messengerの使用
  • AIDLの使用

説明を読む限りでは、こうか。

  • アプリ専用に Serviceを用意してアプリと同じプロセスで実行する場合は、Binderクラスを拡張する
  • 異なるプロセスで実行されるなら、Messengerを使用する
  • AIDLはおすすめしない

おすすめしない理由もしっかり調べるべきだろうが、今回はスルーだ。 Messenger を使うやり方は AIDLを内部で使っていそうなことを書いてある。 AIDL は昔からあったと思うのだが、使い方が危ういから Messengerでラップしたとかだろうか?

まあいい。ただでさえ進まないので、AIDL については私は調べないということにして、出てきたら考えよう。


まず、Binderクラスを拡張するやり方から見ていく。

同一プロセスで動作するのだから、メモリ空間も同じだ。
となると、マルチスレッドで動作して、オブジェクトは Mutexで排他しながら使うのだろうか。共有メモリのように大きな排他システムを使わなくてよいので、パフォーマンスが良くなるとかじゃなかろうか。

なにより、アプリから Serviceのメソッドを直接呼び出せるというのがよい。直感的だ。 Activityで全部実装した後で、やっぱりここは Serviceにしよう、という場合にも移動させやすいのだと思う。

 

この節で説明に使っている LocalServiceは、 randomNumberの getterだけが publicになったクラスだ。 getterが呼ばれるたびに乱数を返す。

そして onBind()では IBinderを返すのだが、これは constな LocalBinderクラスのインスタンスを返すだけ。この LocalBinderクラスが Binderクラスを拡張したものである。
何をやっているかというと、getService()関数だけを定義していて(Binderを継承しているのでオーバーライドしているのかな?)、それは自分自身を返している・・・?

ちょっと Kotlinの読み方が分からないので、調べる。

01:     inner class LocalBinder : Binder() {
02:         // Return this instance of LocalService so clients can call public methods
03:         fun getService(): LocalService = this@LocalService
04:     }

まず、 Binderクラスを継承している。 Kotlinは class内に classが定義できる(nested class)し、内部classも定義できる(inner class)。 あと、無名内部class(anonymous inner class)もある。 Javaもそんな感じだったか。

このページだけ読むと、inner classにしておくと外側の classが持つ変数もアクセスできるように見える。それだけなのか??

 

と、中途半端なところで今日は終わり。

0 件のコメント:

コメントを投稿

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