重新打开应用程序后,创建了一个服务的多个实例

After reopening application, multiple instances of a service are created

我正在尝试创建一个应用程序来更新持久通知,即使该应用程序已关闭。现在,我正在使用在 MainActivity 的 onCreate():

中启动的服务
serviceIntent = Intent(this, PersistentService::class.java)
val stopped = stopService(serviceIntent)
println("[123] stopped: $stopped")
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(serviceIntent)
} else {
    startService(serviceIntent)
}

这非常适合启动它。然而,当我重新打开并关闭应用程序时,即使打印了 stopped: true ,之前的服务仍然是 运行 并且之前服务的 stopService() 没有被调用。

PersistentService 的精简版本class:

var timesStarted = 0
var lastService: PersistentService? = null

class PersistentService: Service(){
    private var timer: Timer? = null
    private var task: AsyncTask<*, *, *>? = null

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        timesStarted++
        println("[123]starting persistent service. timesStarted: $timesStarted lastService===this: ${lastService===this} lastService==this: ${lastService==this} lastService: $lastService")
        println("[123] hashCode: ${hashCode()}")
        lastService = this
        if(timer == null){
            timer = Timer()
        }
        setToLoadingNotification()
        timer?.scheduleAtFixedRate(object : TimerTask(){
            override fun run(){
                println("[123]Updating hashCode: ${this@PersistentService.hashCode()}")
                if(task?.status == AsyncTask.Status.RUNNING){
                    // send notification saying last request timed out
                }
                task?.cancel(true)

                task = DataUpdaterTask(DatabaseDataRequester { GlobalData.connectionProperties }) { dataRequest ->
                    // send notification based on dataRequest value
                }.execute()
            }
        }, 1000L, UPDATE_PERIOD)
        return START_STICKY
    }

    private fun notify(notification: Notification){
        getManager().notify(NOTIFICATION_ID, notification)
        startForeground(NOTIFICATION_ID, notification)
    }
    private fun getBuilder(): Notification.Builder {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            return Notification.Builder(this, NotificationChannels.PERSISTENT_STATUS.id)
        }
        return Notification.Builder(this)
    }
    private fun getManager() = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    override fun stopService(name: Intent?): Boolean {
        println("[123]Stopping persistent service")
        timer?.cancel() // stop the timer from calling the code any more times
        task?.cancel(true) // stop the code from running if it's running
//        getManager().cancel(NOTIFICATION_ID)
        return super.stopService(name)
    }
}

这是输出

[123] stopped: false
[123]starting persistent service. timesStarted: 1 lastService===this: false lastService==this: false lastService: null
[123] hashCode: 4008007
[123]Updating hashCode: 4008007
[123]Got successful data request
[123]Updating hashCode: 4008007
[123]Got successful data request
// *close and reopen the app*
[123] stopped: true
[123]starting persistent service. timesStarted: 2 lastService===this: false lastService==this: false lastService: me.retrodaredevil.solarthing.android.PersistentService@3d2847
[123] hashCode: 7823272
[123]Updating hashCode: 7823272
[123]Got successful data request
[123]Updating hashCode: 4008007
[123]Got successful data request
[123]Updating hashCode: 7823272
[123]Got successful data request

从输出中可以看出,两个服务同时 运行。哈希码显示它们不是同一个对象,所以如果我将代码放在 onCreate() 而不是 onStartCommand() 中并不重要(我已经测试过了)

如果有人能指出正确的方向,那将很有帮助。我是 android 开发的新手,我很难找到正确的方法来做到这一点。我什至不确定我现在正在做的是否是更新通知的最佳方式。

and the previous service's stopService() was not called.

stopService() 不是 Service 的生命周期方法。也许你在想 onDestroy().

the previous service is still running

否,之前的服务实例已停止。你刚刚泄露了 Timer,因为你没有在 onDestroy().

中取消 Timer

所以,覆盖 onDestroy(),将你的 cancel() 调用放在那里,摆脱其余的 stopService(),你应该处于更好的状态。