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