Serviceは、Androidシステムによって、終了させられてしまうことがあります。
bindしているActivityが全ていなくなったとか、Low Memoryになったとか。
Serviceには、onDestroy()も、onLowMemory()も存在してますので、
終了させられても、この2つをちゃんと実装しておけば良い・・・
と思いきや、
そんなの呼ばれずにKillされてしまうシチュエーションがあります。
ちょっとググれば、LowMemoryでは、そうなってしまうことがあるようなことがわかりますが、それだけではありません。
だれもそのServiceにbindしてない状態ですと、LowMemoryとか関係なく、一定時間経つとKillされます。
定期的に処理を行っていたとしても、本当に、Killされちゃいます。
onDestroyとか一切呼ばれません。
ServiceがKillされちゃうあたりで、"No longer want xx.service (pid xxxxx): hidden #xx"といったLogが出てきますが、このLogがあるのがframework/base/services/ActivityManagerService.java です。
コードを覗いてみると(12/24版のGingerBread)、
12170行目に、このLogをだしてます。そのちょっと下、12175行目で、やはり、います。
ProcessのKillが。
if (app.curAdj >= HIDDEN_APP_MIN_ADJ) { if (!app.killedBackground) { numHidden++; if (numHidden > MAX_HIDDEN_APPS) { Slog.i(TAG, "No longer want " + app.processName + " (pid " + app.pid + "): hidden #" + numHidden); EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, app.processName, app.setAdj, "too many background"); app.killedBackground = true; Process.killProcessQuiet(app.pid); } } }これでは、onDestroyも呼ばれないのも納得・・・
この動作を避けるためには、Service::startForeground()を、必要なタイミングで呼べばいいです。
実際、ActivityManagerServiceでも、Foreground ServiceはKillしないようにしてます(※)
(※)正確には、Killされにくくなる、みたいです。どれから順番にKillするかはcomputeOomAdjLocked()を読めば良さそう。
Notification notification = new Notification(R.drawable.icon, getString(R.string.StartNotification), System.currentTimeMillis()); Intent t_intent = new Intent(this, Target.class); t_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent intent = PendingIntent.getActivity(this, 0, t_intent,0); notification.setLatestEventInfo(this, getString(R.string.app_name), getString(R.string.Notification), intent); notification.flags = Notification.FLAG_ONGOING_EVENT; startForeground(FORGROUND_ID, notification);Notificationが必要なので、それを作って、startForeground()を呼んであげます。startForeground()の第1引数はNotificationに渡す識別用のIDです。
これで、たいていのシチュエーションではKillされないと思います。
が、ServiceのAPI仕様書にもありますが、Critical な Low Memory状態だと、今画面に出てるActivityから
使われてても、ServiceがKillされるようなこともあるらしいので(気にしなくていいらしいけど)、
Killされる可能性があるというのは、頭の片隅においてServiceを設計したほうが良さそうです。
0 件のコメント:
コメントを投稿