同时调用多个 API,并在相应请求处理完成后立即更新 UI Android

2024-05-19

我需要跑6个API同时调用并且需要在相应的请求完成时更新每个用户界面

目前我正在使用kotlin 协程并行执行使用以下代码

    suspend fun getAllData() : List<String>{
    return withContext(Dispatchers.IO) {

        lateinit var getObject1Task: Deferred<Response<String>>
        lateinit var getObject2Task: Deferred<Response<String>>
        lateinit var getObject3Task: Deferred<Response<String>>

        lateinit var getObject4Task: Deferred<Response<String>>
        lateinit var getObject5Task: Deferred<Response<String>>
        lateinit var getObjec6Task: Deferred<Response<String>>

        launch {
            getObject1Task = dataApiService.getData()
            getObject2Task = dataApiService.getData()
            getObject3Task = dataApiService.getData()
            getObject4Task = dataApiService.getData()
            getObject5Task = dataApiService.getData()
            getObject6Task = dataApiService.getData()
        }

          var stringList = ArrayList<String >()

        stringList.add(getObject1Task.await().body()!!) /// add All to the list
        stringList
    }
}

我无法找到一种方法来在 API 完成后立即获取每个字符串的数据。 我也尝试过LiveData但有些人认为这是有道理的。

每个字符串彼此之间没有链接,因此不必将所有字符串添加到列表中


使用协程,有多种方法可以实现这一点。这里有 2 个例子:

  1. Use launch不返回值并直接更新 UI 一旦字符串准备好,就在协程内。
  2. 与您的方法类似,您也可以使用async, 等待 未来响应返回值然后更新UI。

示例 1:即发即忘,每个元素准备好后直接更新 UI

从协程内更新 UI 元素时,应使用 Dispatchers.Main 作为协程上下文。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)


    repeat(6){index ->
        val id = resources.getIdentifier("tv${index+1}", "id", packageName)
        val textView = findViewById<TextView>(id)
        textViews.add(textView)
    }

    repeat(6){ index ->
        GlobalScope.launch(Dispatchers.Main) { // launch coroutine in the main thread
            val apiResponseTime = Random.nextInt(1000, 10000)
            delay(apiResponseTime.toLong())
            textViews[index].text = apiResponseTime.toString()
        }
    }
}

笔记: 在这里,一旦字符串准备好,每个 TextView 就会更新,而不会阻塞主线程。 我在 LinearLayout 中使用了 6 个示例 TextView,ID 为“tv1”、“tv2”...

示例 2:使用并行 async + wait(),在所有作业完成时更新 UI(与您的类似)

在这里,我们并行启动 6 个异步,并在结果准备好后立即将其添加到列表中。添加最后一个结果后,我们返回列表并循环更新 TextView。

val textViews = mutableListOf<TextView>()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    repeat(6){index ->
        val id = resources.getIdentifier("tv${index+1}", "id", packageName)
        val textView = findViewById<TextView>(id)
        textViews.add(textView)
    }
    // note: again we use Dispatchers.Main context to update UI
    GlobalScope.launch(Dispatchers.Main) {
        val strings = updateUIElementAfterThisFinishes()
        repeat(6){index ->
            textViews[index].text = strings[index]
        }
    }

}

 // for API calls we use Dispatchers.IO context, this function will finish at 10 seconds or less
suspend fun updateUIElementAfterThisFinishes(): List<String> = withContext(Dispatchers.IO){
    val strings = mutableListOf<String>()
    val jobs = Array(6){GlobalScope.async {
        val apiResponseTime = Random.nextInt(1000, 10000)
        delay(apiResponseTime.toLong())
        apiResponseTime.toString()
    }}
    jobs.forEach {
        strings.add(it.await())
    }
    return@withContext strings
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

同时调用多个 API,并在相应请求处理完成后立即更新 UI Android 的相关文章

  • Twowayview 滚动时自动添加内边距

    我在用双向视图 https github com lucasr twoway view在我的一个项目中 这是android的扩展回收者视图 https developer android com reference android supp
  • 对话框片段嵌入取决于设备

    在我的应用程序中 用户从联系人或通话记录中选择电话号码 选择联系人非常简单 并且在手机和平 板电脑上都可以很好地工作 i e 在手机上会弹出新的全屏活动 在桌子上我会看到带有联系人列表的漂亮弹出对话框 似乎无法从通话记录中选择电话号码 因此
  • 当前版本的Android Gradle插件不支持按需配置

    升级到 Android Studio 3 1 2 后 出现以下错误 当前版本的 Android Gradle 插件不支持按需配置 因为您使用的是 Gradle 4 6 或更高版本 建议 通过在 gradle properties 文件中设置
  • 地理编码 API 与地理编码器

    在我的应用程序中 我需要使用地理编码 但我不太清楚该使用哪种方法 直到昨天我在URL中添加了参数maps googleapis com maps api geocode json address myparameter sensor fal
  • 我如何从android中的复选框获取值

    我想获取复选框中所选项目的名称 但我只得到一些字母数字 如何从复选框中获取所选项目的名称 public View getView int position View convertView ViewGroup parent View vie
  • 如何在其他呼叫运行时以编程方式合并呼叫(电话会议)

    我的要求是这样的 假设我当时正在拨打一个号码 并且我想以编程方式拨打另一个号码 到目前为止 我所做的是 当某些呼叫已经进行时 我能够呼叫特定号码 例如 假设我正在拨打号码 123 1 分钟后 通过使用Alarm Manger我触发一个事件来
  • Android WebView文件上传

    我正在开发一个 Android 应用程序 基本上它是一个WebView和一个进度条 Facebook 的移动网站 m facebook com 已加载到WebView 当我单击 选择文件 按钮上传图像时 没有任何反应 我已经尝试了所有的解决
  • 该项目可能使用的 Gradle 版本不包含“compileSdkVersion()”方法

    当我尝试运行最初在 Eclipse ADT 上创建的项目时 我遇到了这个问题 Error 17 0 Gradle DSL method not found compileSdkVersion Possible causes ul li Th
  • 合并 dex 程序类型已存在时出错:android.support.v4.os.ResultReceiver$MyResultReceiver

    合并dex时出错 以下是依赖项 ext anko version 0 10 5 support lib 1 0 0 alpha1 room lib 1 1 0 dependencies implementation org jetbrain
  • 如何在CUDA应用程序中正确应用线程同步?

    一般来说 我在应用程序中偶尔会使用线程同步 因为我并不经常需要此功能 我并不是真正的高级 C C 程序员 但我也不是初学者 我开始学习 CUDA C 对当今 GPU 与 CPU 的能力相比感到兴奋 我意识到 CUDA 编程主要是关于并行线程
  • 数据未刷新“DynamiteModule:未找到 com.google.firebase.auth 的本地模块描述符类”

    我已经使用 Firebase 很长时间了 到目前为止 除了以下场景之外 一切都很好 有时我注意到我的应用程序不再获取新数据 我正在用一个活跃的监听器监听变化 并且我确实有keepSynced set to true 发生这种情况时 我会在日
  • 垂直从上到下线手势检测器

    我用的是 手势工具 注意到对于垂直从上到下的线无法检测 因为我在代码中使用生成的手势文件 如下所示 但无法检测垂直从上到下的线手势检测 import java util ArrayList import android app Activi
  • Flutter - 删除 ListView 中项目之间的空间

    我正在使用 ListView builder 函数来创建项目列表 然而 iOS 中每个项目之间的空间很大 截图 你知道如何删除项目吗 看来是默认的 因为我没有添加它 code 列表显示 return Scaffold body ListVi
  • 使用并行任务库时“foreach”失败

    以下代码创建正确数量的文件 但每个文件都包含第一个列表的内容 有人能发现我做错了什么吗 private IList
  • 如何关闭导航抽屉以使用返回主页图标按钮?

    我也将操作栏与搜索栏一起使用 并且我需要像后退按钮一样使用 ActionBar ico 但我也在使用导航抽屉 如何关闭 隐藏 禁用导航抽屉菜单以使用后退按钮 我的 ActionBar 代码 Override public boolean o
  • Android 10 请求 ACTIVITY_RECOGNITION 权限

    我试图遵守 Google 的要求 为 Android 10 请求 ACTIVITY RECOGNITION 权限 但我似乎不明白为什么没有显示权限弹出窗口 就像其他权限 即位置 存储等 一样 我的代码是 if ContextCompat c
  • 如何检测日期选择器对话框的取消单击?

    我正在使用以下 日期选择器的示例 http developer android com guide tutorials views hello datepicker html http developer android com guide
  • Android Studio 中自动打开“运行设备”选项卡

    在 Android Studio Flamingo 中有一个名为跑步设备并且它会在每次之后自动打开运行应用程序 有办法禁止这个自动打开吗 我尝试禁用启用物理 Android 设备的镜像选项 但选项卡仍然自动打开 基于此issue https
  • 在 Qt 中构建 Android 项目不再有效

    所以我对 Android SDK NDK 和 Apache Ant 进行了一些更新 现在我无法构建任何 Android 项目 我收到一条警告 然后它说找不到 build xml 文件 错误 Warning Android platform
  • 应用程序关闭时单击 Firebase 通知后打开特定活动/片段

    我知道这个问题似乎重复 但根据我的要求 我在网上搜索了很多帖子 但没有任何对我有用 我的要求 我正在使用 Firebase 来获取推送通知 当应用程序打开时意味着一切正常 但我的问题是 如果有任何推送通知出现 应用程序处于后台 关闭意味着我

随机推荐