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

标签 android kotlin android-service android-notifications

我正在尝试创建一个应用程序来更新持久通知,即使在应用程序关闭时也是如此。现在,我正在使用在 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 类的简化版本:

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() 的其余部分,而且你应该处于更好的状态。

关于android - 重新打开应用程序后,创建了一个服务的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53366592/

相关文章:

kotlin - 未找到生成的类

android - 在 Android 应用程序中使用信任代理

android - 不确定这里是否需要 WakeLock

android - 触发自动生成代码Android导航

android - 使用应用内计费隐藏广告横幅

java - Android - 如何选择上下文?

android - 图像尺寸加倍

java - 如何使用 Hibernate 将 UUID 作为主键在两个表中共享?

Android - 使用 gradle 3.2.1 构建数据绑定(bind)和 kapt 失败

java - 如何销毁/终止服务?