如何从 Fragment 或 Activity 调用挂起功能?

Nur*_*lov 9 android kotlin-coroutines

我想请求许可并通过非阻塞函数来完成。因为我需要 Context,所以我不能从 ViewModel 调用它。如何为片段提供默认 UI 范围并像这样调用挂起函数:

class MapsFragment : Fragment() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?

    launch {
         withContext(Dispatcher.Main){
           checkLocationPermission().await()
        }
    }
 }
}


suspend fun checkLocationPermission():Boolean{...}
Run Code Online (Sandbox Code Playgroud)

Nur*_*lov 18

在文档https://developer.android.com/topic/libraries/architecture/coroutines 中说我可以使用androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01ktx。

class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewLifecycleOwner.lifecycleScope.launch {
        val params = TextViewCompat.getTextMetricsParams(textView)
        val precomputedText = withContext(Dispatchers.Default) {
            PrecomputedTextCompat.create(longTextContent, params)
        }
        TextViewCompat.setPrecomputedText(textView, precomputedText)
    }
 }
}
Run Code Online (Sandbox Code Playgroud)

  • 活动怎么样? (3认同)
  • @roghayehhosseini,您需要导入这两个依赖项,**实现“androidx.fragment:fragment-ktx:1.4.1”** **实现“androidx.activity:activity-ktx:1.4.0”** (2认同)

Boo*_*tak 5

您可以使用

GlobalScope.launch {

}
Run Code Online (Sandbox Code Playgroud)

或者

使您的片段/活动实施 CoroutineScope

并像这样设置默认调度程序。

class Fragment : CoroutineScope {
     
     private val job = Job()
     override val coroutineContext: CoroutineContext
            get() = job + Dispatchers.Main 

     . . .

     override fun onDestroy() {
        super.onDestroy()
        job.cancel()
     }

}
Run Code Online (Sandbox Code Playgroud)

然后你可以像你在问题中附加的代码一样调用挂起函数。

更新

活动/片段的协程范围可以这样定义。

class Fragment : CoroutineScope by MainScope() {
         
        
    ... 
         override fun onDestroy() {
            super.onDestroy()
            cancel()
         }
    
    }
Run Code Online (Sandbox Code Playgroud)

  • 这种方法现在已经过时了,你应该让库来处理它:`class Fragment : CoroutineScope by MainScope {`。它将使用正确的“SupervisorJob”而不是普通的“Job”。请参阅 [CoroutineScope](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/) 上的文档,您仍然必须覆盖 destroy 回调:`override fun onDestroy() { 取消() }` (4认同)