首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当包含Coroutine的服务停止时,Coroutine不会停止

当包含Coroutine的服务停止时,Coroutine不会停止
EN

Stack Overflow用户
提问于 2021-07-12 20:10:16
回答 2查看 1.4K关注 0票数 1

我有一个前台服务,可以延迟更改壁纸,所以我在里面使用协同器,我用startService(意图(这个,MySerivce::class.java))从另一个类调用它,但是当我用stopService(意图(这个,MySerivce::class.java))停止它时,只在主线程停止上运行(比如showNotification()),下面是我的代码:

代码语言:javascript
复制
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
}
}

和这里的manageWallpapers函数

代码语言:javascript
复制
private suspend fun manageWallpapers(list: Array<File>?, time:Int){

    while (true){
        if (list != null) {
            for (image in list){

                setWallpaper(image)
                delay(time.toLong())
                
            }
        }

    }

    
}
EN

回答 2

Stack Overflow用户

发布于 2021-07-12 20:31:27

您需要保留对launch返回的作业的引用,并在服务停止时调用cancel()

代码语言:javascript
复制
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()
}

另一种选择是保留对CoroutineScope的引用并在其上调用cancel

票数 5
EN

Stack Overflow用户

发布于 2021-07-12 21:16:51

如果您来自LifecycleService的子类,您可以使用lifecycleScope启动您的协同服务,因此当服务停止时,它将被自动取消。

build.gradle

代码语言:javascript
复制
implementation 'androidx.lifecycle:lifecycle-service:2.3.1'

在您的服务中,LifecycleService的一个子类

代码语言:javascript
复制
lifecycleScope.launch {
    val time = intent?.getIntExtra("TIME",0)
    if (time != null) {
        manageWallpapers(list,time)
    }
}

不需要指定Dispatchers.IO,因为您只是在调用挂起函数,而不是阻塞函数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68353369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档