Android Service

James Lin
5 min readJul 1, 2018

--

如果不想讓系統殺掉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

--

--

James Lin
James Lin

No responses yet