问题描述
我有一个应用程序,可以从某项活动中在前台启动服务。使用完该应用程序后,我需要能够在该应用程序被终止(清除)后销毁该服务。
为此,我使用了 Kotlin对象/单个,因为这似乎是服务与视图模型之间进行通信的最简单方法,在这里我可以使用{{1} }方法来更改将用于销毁服务的状态。在服务内部,我使用协程来检查应用程序是否每秒仍在运行。 应用程序的状态存储在对象中。如果该应用程序还没有运行,我将销毁该服务。
我遇到的问题是,第一次打开应用程序时,该对象已正确初始化,但是当我杀死它并再次启动时(第二次),该对象的初始化永远不会发生。
这很容易看到,因为启动应用程序后立即关闭了通知,这是因为状态onCleared
为isAlive
,如果初始化了对象,则状态应该为false
。
如果我再次杀死该应用程序,然后再次启动它(第3次),则这次初始化正确完成。这种行为不是随机的。
我发现,如果我不调用true
方法(我需要),则每次都会正确初始化对象,而不会出现异常,因此我想有些事情会改变行为startForeground
被调用时的系统状态。
我已经在模拟器和物理设备上对其进行了测试,结果相同。
我附上了完整的代码,因此您可以轻松地复制行为。
非常感谢您!
MainActivity.kt
startForeground
MainService.kt
package com.example.appwithsingletontest
import android.app.NotificationChannel
import android.app.notificationmanager
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.activity.viewmodels
const val notificationChannelID = "channel_01"
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
createNotificationChannel() //Should be called as soon as the app starts.
val vm: Activityviewmodel by viewmodels()
vm.dummy = true //Used to initialize the viewmodel (Lazy initialization).
setContentView(R.layout.activity_main)
val intentService = Intent(this,MainService::class.java)
startService(intentService)
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = getString(R.string.channel_name)
val descriptionText = getString(R.string.channel_description)
val importance = notificationmanager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(notificationChannelID,name,importance).apply {
description = descriptionText
}
// Register the channel with the system
val notificationmanager: notificationmanager = getSystemService(Context.NOTIFICATION_SERVICE) as notificationmanager
notificationmanager.createNotificationChannel(channel)
}
}
}
Activityviewmodel.kt
package com.example.appwithsingletontest
import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import kotlinx.coroutines.*
class MainService : Service() {
private val job = SupervisorJob()
private val scope = Coroutinescope(dispatchers.Main + job)
private val ONGOING_NOTIFICATION_ID = 1
private lateinit var notification : Notification
override fun onCreate() {
val pendingIntent: PendingIntent =
Intent(this,MainActivity::class.java).let { notificationIntent ->
PendingIntent.getActivity(this,notificationIntent,0)
}
notification = NotificationCompat.Builder(this,notificationChannelID)
.setContentTitle(getText(R.string.notification_title))
.setSmallIcon(R.drawable.ic_launcher_background)
.setNotificationSilent()
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.build()
startForeground(ONGOING_NOTIFICATION_ID,notification)
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?,flags: Int,startId: Int): Int {
val isAppAlive = DataBridge.appIsAlive()
scope.launch {
while(true){
delay(1000)
if(!DataBridge.appIsAlive()) {
stopForeground(true)
stopSelf()
}
}
}
return START_NOT_STICKY
}
override fun onDestroy() {
job.cancel()
Log.i("AWST MainService","####### THE END #######.")
}
}
DataBridge.kt
package com.example.appwithsingletontest
import android.util.Log
import androidx.lifecycle.viewmodel
class Activityviewmodel : viewmodel(){
var dummy = false
override fun onCleared() {
super.onCleared()
DataBridge.appWasKilled()
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)