如果不想讓系統殺掉app,可以把Service的優先權提高一點。
Foreground Service,當系統進入 sleep mode 的時候,可能會把整個Process砍掉,這個時候,連一般的Service都無法存活!!!!!!
如果使用 Foreground Service,被殺掉的機率會小很多,除非系統記憶體很吃緊的時候。
在 Service 的 onCreate()的時候,使用startForeground(1,mBuilder.build()),來宣告Service的權限,最大的不同點是使用這個權限時,需要傳入一個Notification。
override fun onCreate() {
super.onCreate()
Log.d("Start"," Foreground")
var mBuilder = NotificationCompat.Builder(this, "MyNotifi")
.setSmallIcon(R.drawable.notification_icon_background)
.setContentTitle("ha")
.setContentText("pp")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
startForeground(1,mBuilder.build())
}
在此範例,我是在 service 開 Thread 來監控休眠模式的Service有無被殺掉。
跑了5百多秒,還沒被殺掉。
沒有用Foreground的話。
Background Service
主要是透過 onStartCommand()
的回傳值來決定 Service 被殺掉時要怎麼做對應的處理。
Service 的三種優先權:
START_NOT_STICKY
:如果系統在 onStartCommand()
後終止 Service,除非有待決的 intent 要傳送,否則請「不要」建立 Service。
START_STICKY
:如果系統在 onStartCommand()
後終止 Service,請重新建立 Service 並呼叫 onStartCommand()
,但「不要」重新傳送最後的 intent。 相反地,除非有待決的 intent 要啟動 service,否則系統會使用 null intent 呼叫,適用於媒體播放程式 。
START_REDELIVER_INTENT
:如果系統在 onStartCommand()
後終止 Service,請重新建立 Service 並使用傳送至 Service的最後 intent 呼叫onStartCommand()
。適用的 Service 為主動執行如下載檔案等應該立即繼續的工作。
小插曲:
在模擬器(不同型號的手機)上,我使用一般的Service不會被殺掉,但是在我的實體手機( ASUS )上卻被殺掉了,手機型號不同似乎有很大的影響阿。
更新Foreground Service的Notification
直接使用 startForeground(1,customerNotification),Create Notification的時候可以先用東西儲存他,或者是用Notification的id去跟NotificationManager拿Notification,接著再startForeground(1,customerNotification){1:指的是一開始startForeground的id}。
e.g.
override fun updateExoPlayerState() {
if (ExoPlayerManager.isPlay()) {
remoteViews!!.setImageViewResource(R.id.playStopSongImageView, R.drawable.ic_play_arrow_black_24dp)
} else {
remoteViews!!.setImageViewResource(R.id.playStopSongImageView, R.drawable.ic_pause_black_24dp)
}
startForeground(1,customerNotification)
}
Foreground Service:GitHub
MusicApp(update Notification):GitHub