如何从 Fragment 或 Activity 调用挂起函数?

How to call suspend function from Fragment or Activity?

我想请求权限并通过非阻塞函数来完成。因为我需要上下文,所以我不能从 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{...}

像这样尝试:

suspend fun foundError() {
coroutineScope {
    async { 
        throw StructuredConcurrencyWill("throw")
    }
 }
}

您可以使用

GlobalScope.launch {

}

让你的fragment/activity实现CoroutineScope

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

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

     . . .

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

}

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

更新

activity/fragment 的协程作用域可以这样定义。

class Fragment : CoroutineScope by MainScope() {
         
        
    ... 
         override fun onDestroy() {
            super.onDestroy()
            cancel()
         }
    
    }

我们可以 return 从函数中调用 MutableLiveData 并等待协程工作并 return 返回。

fun fetchDocuments(): MutableLiveData<TodoResponseModel> {
    val mutableLiveData = MutableLiveData<TodoResponseModel>()
    Log.d("COROUTINE", "Main Context started")
    GlobalScope.async(Dispatchers.Main) {
        Log.d("COROUTINE", "IO Context started")
        val response = repository.getTodoCoroutineFourth()
        Log.d("COROUTINE", "IO Context completed")
        mutableLiveData.value = response.body()
        Log.d("COROUTINE", "IO Context finished")
    }
    Log.d("COROUTINE", "Main Context ended")
    return mutableLiveData
}

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

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)
    }
 }
}