背景
自作の Service が起動中かどうかをチェックしたかったので調べたのでメモ.
検索してみると, 以下の StackOverflow に最終的に行き着いた.
How to check if a service is running on Android? - stackoverflow
しかし, 上記の方法だと, ActivityManager#getRunningService(Int)
が Android 8.0 から Deprecated になっているため, 現在は使うことができない.
他の手段を調べた結果, LocalBroadcastManagerを使えば出来そうだということが分かったので, これを使って実装してみた.
LocalBroadcastManager
自身のプロセス内にのみBroadcastされる Intent を発行できるやつです. 受信側が自身のプロセス内であることが保証されるので安全です. (Deeplink を自身のプロセスで起動した場合はその限りではないかも)
EventBus なんかと似たような動作をします.
実装
LocalBroadcastManager#sendBroadcast
は送信に成功したかどうか(受信側が存在していたるかどうか)を返り値で取得できる. つまり, Service が起動している間だけ受信側を用意すれば, その返り値によって Service の起動状態を確認することができる.
具体的には, Service 側で以下のような実装をする.
class HelloService : Service() {
companion object {
const val ACTION_IS_RUNNING = "com.example.HelloService_is_running"
fun createIntent(context: Context) = Intent(context, HelloService::class.java)
fun isRunning(context: Context): Boolean {
return LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(ACTION_IS_RUNNING))
}
}
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(applicationContext) }
// BroadcastReceiver側の処理は不要
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// no op
}
}
override fun onBind(intent: Intent?): IBinder? = null
override fun onCreate() {
super.onCreate()
// Receiver の登録
localBroadcastManager.registerReceiver(broadcastReceiver, IntentFilter(ACTION_IS_RUNNING))
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// startForegroundService(..., ...)
return START_STICKY
}
override fun onDestroy() {
// Receiver の登録解除
localBroadcastManager.unregisterReceiver(broadcastReceiver)
super.onDestroy()
}
onDestroy
で登録解除をしているが, 実際には無くても問題はない. Service が stop されたときやシステムによってキルされたときにも, 同様に BroadcastReciver も無効になるからである.
Service側の comapnion object に isRunning(context: Context)
を用意し, このメソッドを呼ぶだけで起動状態を確認できるようにした. これにより, Activity などの確認側に LocalBroadcastManager
などの知識を持ち込まずに済む.
以上の実装によって, 確認側は HelloService.isRunning(context)
を呼ぶだけで Service の起動状態を確認できるようになった.
まとめ
調べて出てくるのは Deprecated になった方法だけ 😲
LocalBroadcastManager を用いて Servie の起動状態をチェックできた