繁体   English   中英

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

[英]How to call suspend function from Fragment or Activity?

我想请求许可并通过非阻塞函数来完成。 因为我需要 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{...}

在文档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)
    }
 }
}

您可以使用

GlobalScope.launch {

}

或者

让你的片段/活动实现CoroutineScope

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

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

     . . .

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

}

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

更新

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

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

试试这样:

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

我们可以从函数返回一个MutableLiveData并等待协程工作并返回。

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM