簡體   English   中英

Android 服務在啟動后 10 秒被殺死

[英]Android service is killed 10 seconds after start

我需要提供服務以通過 websocket 捕獲服務器消息並在通知中顯示它們。 當我第一次關閉應用程序時,服務停止了。 我在onDestroy中制作了一個廣播接收器,以在應用程序關閉並從活動應用程序中滑動后重新啟動服務。 但畢竟系統或其他一些東西會每隔 10 秒准確地殺死服務。 我看到Not finishing the service, sending broadcast ,所以不是我使用命令停止服務。

logcat 中每 10 秒出現一次“啟動命令”消息,這意味着該服務每 10 秒不斷重啟。

NotificationPuller.kt

import android.app.Notification
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.util.Log
import com.packagename.project.ENDPOINT_SERVER_WS
import com.packagename.project.PREFS
import com.packagename.project.PREFS_TOKEN
import com.packagename.project.UnsafeHttpClient
import com.packagename.project.receivers.ServiceRestart
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.WebSocket
import java.util.*

class NotificationPuller : Service() {

    private var finishing: Boolean = false

    override fun onBind(intent: Intent): IBinder? {
        Log.d(TAG, "Service binding")
        return null
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "Start command")
        return START_STICKY
    }

    private fun onCriticalFailure() {
        Log.d(TAG, "Critical failure, stopping the service")
        stopService()
    }

    private fun onFailure() {
        Log.d(TAG, "Connection failure")
    }

    override fun onDestroy() {
        super.onDestroy()
        if(!finishing) { // not killing the service completely, restarting it
            Log.d(TAG, "Not finishing the service, sending broadcast")
            val broadcastIntent = Intent()
            broadcastIntent.setClass(this, ServiceRestart::class.java)
            broadcastIntent.action = RESTART_ACTION
            sendBroadcast(broadcastIntent)
        } else
            Log.d(TAG, "Service destroyed")
    }

    private fun stopService() {
        finishing = true
        stopSelf()
    }

    companion object {
        private const val TAG = "SERVICE"
        const val RESTART_ACTION = "com.nikitiyproject.RESTART_ACTION"
    }
}

服務重啟.kt

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.core.content.ContextCompat
import androidx.core.content.IntentCompat
import com.packagename.project.background.NotificationPuller

class ServiceRestart : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Log.d(TAG, "BroadcastReceiver restarts service")
        val serviceIntent = Intent(context!!, NotificationPuller::class.java)
        ContextCompat.startForegroundService(context, serviceIntent)
    }

    companion object {
        private const val TAG = "BCR"
    }
}

引用startForegroundService()的文檔

與 startService(android.content.Intent) 類似,但帶有隱式 promise,服務將在開始運行時調用 startForeground(int, android.app.Notification) 為服務提供與 ANR 間隔相當的時間來執行此操作,否則系統將自動使進程崩潰,在這種情況下,在運行 SDK 版本 Build.VERSION_CODES.S 或更高版本的設備上的 logcat 上會記錄內部異常 ForegroundServiceDidNotStartInTimeException。 在較舊的 Android 版本上,會記錄內部異常 RemoteServiceException,並帶有相應的消息。

(重點補充)

您沒有在Service中調用startForeground()以遵守 promise。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM