2014年2月8日土曜日

BroadcastReceiver

Base class for code that will receive intents sent by sendBroadcast().
android.content.BroadcastReceiver

概要

イメージせよ。

BroadcastをReceiveする当番。

Android端末内にはブロードキャストがアホみたいに飛び交っている。
で、このレシーバがそれらを受信する。クールでかっこいいですね〜

レシーバ自体はブロードキャストが来た時に起動して、処理が終わったら消える。

登録が必要。

ただBroadcastReceiverを作っておけばおkwwwという世界観ではなくて、
AndroidManifest.xmlに登録する必要がある。

ActivityAndroidManifest.xmlに定義するんだから仕方あるまい。
と思う人はそれでいい。

納得行かない人は動的にも登録できるよ。

受け取るブロードキャスト。

何も設定しないと全部受け取る。
他のアプリケーションから受け取らない設定にもできる。exported="false"な。

ICSからはブロードキャストを送るときにIntent.setPackageによって、
受信相手のパッケージ名を指定できる。

まあでもアプリケーション間通信とかしたいわけじゃないってときは、
LocalBroadcastReceiverってのがあるから。それ使って。

すぐ死ぬ。

onReceive(Context, intent) が呼ばれると生き、returnした後に殺されうる。
なので非同期処理はできない。なぜならcallbackを待つ間に死にかねないから。

例えばダイアログは出せない。てゆーかさ、
バックグラウンドで何かが起こったことを知らせるのは、Notificationだろ?
NotificationManagerを使おう。

殺されやすさ。

onReceive(Context, intent) 実行中ならforegroundプロセスとして扱われる。
よっぽどメモリがアレにならない限り死なない。
で、問題はreturnした後。
殺されやすさは、そのプロセス内の他のアプリケーションに依存する。
もしApplicationと同じプロセスで動かしていたら、
そのApplicationの殺されやすさと同じになるし、
専用のプロセスで動いていたら、空のプロセスとみなされて速攻殺される。

だから、長時間の処理ならServiceと一緒に使うといいよ。
サービスを起動して、処理が終わったら自殺すればいい。

選べるプロセス。

そういうわけで、実行するプロセスが選べる。
Applicationと同じプロセスで実行するか、別のプロセスで実行するか。

registerReceiverで別スレッドにしない限り、
onReceiveはそのプロセスのMainThreadで実行される。
10秒間のタイムアウトが存在するので長時間の処理ならServiceと一緒に(略)
<receiver>タグで指定されたレシーバはreturnしだい死ぬ。

雑感

onReceive(Context, intent)内しか生きられない儚い命だけど、Contextもらえるからね。
Intentから情報をもらって、Contextに対して処理するって使い方っすね。
すぐ死ぬからメンバー変数とか作るのはやめてね。