kha*_*our 4 java android kotlin foreground-service kotlin-coroutines
我有一个前台服务会延迟更改壁纸,因此我在其中使用协程,我使用 startService(Intent(this,MySerivce::class.java)) 从另一个类调用它,但是当我使用 stopService 停止它时(Intent(this,MySerivce::class.java)),仅在主线程停止时起作用(如 showNotification()),这是我的代码:
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val externalStorageState = Environment.getExternalStorageState()
if (externalStorageState.equals(Environment.MEDIA_MOUNTED)){
val root=getExternalFilesDir(null)?.absolutePath
val myDir = File("$root/saved_images")
val list = myDir.listFiles()
if (myDir.exists()&&list.size>=2){
CoroutineScope(Dispatchers.IO).launch {
val time = intent?.getIntExtra("TIME",0)
if (time != null) {
manageWallpapers(list,time)
}
}
}}
showNotification()
return START_STICKY
}
}
Run Code Online (Sandbox Code Playgroud)
这是管理壁纸功能
private suspend fun manageWallpapers(list: Array<File>?, time:Int){
while (true){
if (list != null) {
for (image in list){
setWallpaper(image)
delay(time.toLong())
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要保留对返回的作业的引用launch,并cancel()在服务停止时调用它。
private var job: Job? = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val externalStorageState = Environment.getExternalStorageState()
if (externalStorageState.equals(Environment.MEDIA_MOUNTED)){
val root=getExternalFilesDir(null)?.absolutePath
val myDir = File("$root/saved_images")
val list = myDir.listFiles()
if (myDir.exists()&&list.size>=2){
job = CoroutineScope(Dispatchers.IO).launch { // HERE
val time = intent?.getIntExtra("TIME",0)
if (time != null) {
manageWallpapers(list,time)
}
}
}}
showNotification()
return START_STICKY
}
}
override fun onDestroy() {
job?.cancel()
job = null
super.onDestroy()
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是保留对您的引用CoroutineScope并进行调用cancel。
如果您从 LifecycleService 子类化,则可以使用lifecycleScope它来启动协程,因此当服务停止时它将自动取消。
build.gradle:
implementation 'androidx.lifecycle:lifecycle-service:2.3.1'
Run Code Online (Sandbox Code Playgroud)
在您的服务中,以下子类LifecycleService:
lifecycleScope.launch {
val time = intent?.getIntExtra("TIME",0)
if (time != null) {
manageWallpapers(list,time)
}
}
Run Code Online (Sandbox Code Playgroud)
无需指定 Dispatchers.IO,因为您仅调用挂起函数,而不是阻塞函数。
| 归档时间: |
|
| 查看次数: |
2745 次 |
| 最近记录: |