2011年6月29日水曜日

StatusBarのなかみ



以前、StatusBarに情報表示させるアプリを作った際に
ステータスバーでも自作のViewが表示出来ればいのにーと思ったのでStatusBarについて調べた。自分用のメモなので分かりにくくても仕方がない。

android.app.NotificationManager.notify(String tag, int id, Notification notification)
がアプリからコールされて、そのなかでenqueueNotificationWithTag()がコールされる。
サービスとプロセス間通信していいて、インターフェースのStubは
INotificationManager.Stubで、その実態の中で
com.android.server.StatusBarManagerService.addNotification()
がコールされている。
これも中でIPCのI/Fの
com.android.internal.statusbar.IStatusBar.addNotification()
をコールしている。
これの実態は
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
にIStatusBar.Stubの拡張として定義されているのだが、これがeclipseのパッケージに含まれてないんだよなー。なぜ??
まあいいや。
んで、それを
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
内で利用しているので、
StatusBarService.java内で作られたViewに対して、プロセス間通信を利用して
android.app.NotificationManagerから情報を渡していっている。
情報はStatusBarIcon implements Parcelableをプロセス間でわたして行っている。といったかんじ。

StatusBarIconView.set()からコールされているgetIcon()の中をみると
r = context.getPackageManager().getResourcesForApplication(icon.iconPackage);
みたいな感じにで、他のパッケージのリソースを取得している。
こうやれば他のパッケージが持っているリソースを利用出来るっぽい。
getIcon()の中でリソースのIDをとってDrawableを作成している。
なので、アイコンは自在に変更できそうもない。という結論。

プロセス間通信しまくりで、最終的にはSystemのUIに行ってしまったので、
やっぱり自作Viewの表示は無理そうだ。
でも、ソースを見ていて
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
は面白かった。
Handlerを拡張して自作のHandlerを作成して、
そのハンドラーに対して
mHandler.obtainMessage(MSG_UPDATE_NOTIFICATION, 0, 0, ne).sendToTarget();
みたいにMessageをsendしている。
handleMessageってどんな時に使うのが正解なんだろう?
と思っていたけど、このようにプロセス間通信で情報を取得して
それをUIの変更に反映させたい時には、プロセス間通信用のI/Fの中で
MessageをsendすることでUIスレッドに処理を変えてやることで、いい感じの実装になると感じた。

Handlerとかの仕組みって、どうやって思いついたんだろ?
本当はそれが一番知りたい。。。

0 件のコメント:

コメントを投稿