如何从Fragment或Activity调用suspend函数?

时间:2019-11-26 04:11:57

标签: android kotlin-coroutines

我想请求权限,并通过非阻塞功能进行操作。由于我需要上下文,因此无法从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{...}

4 个答案:

答案 0 :(得分:1)

您可以使用

GlobalScope.lanch {

}

制作片段/活动工具CoroutineScope

并像这样设置默认的Dispatcher。

class Fragment : CoroutineScope {

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

     . . .

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

}

然后,您可以像问题中附加的代码一样调用suspend函数。

更新

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

class Fragment : CoroutineScope by MainScope() {


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

    }

答案 1 :(得分:0)

尝试这样:

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

答案 2 :(得分:0)

我们可以从函数中返回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
}

答案 3 :(得分:0)

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