12.1 Android中协程的基本使用

文章目录

  • 前言
  • 1、导入依赖
  • 2、使用协程获取服务器中的数据
    • 2.1 定义请求回调结果的数据类
    • 2.2 网络请求
  • 3、网络回调结构
  • 4、通过ViewModel处理网络请求数据

前言

在使用协程的时候一直没有一个具体的概念,只知道协程能够使得异步操作等同于同步操作,且不会造成线程阻塞,且第一次使用协程是根据前辈的代码修改而学会的,没有一个规范性的思维,通过查看官方资料将协程的使用重新梳理一遍,一个简单,不麻烦的做法。

1、导入依赖

选择依赖的方式主要分为两种,查看创建项目的时候中Build configuration language的选项选择的某一项,根据项目来选择

Groovy:

dependencies {implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
}

kotlin:

dependencies {implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
}

2、使用协程获取服务器中的数据

目的: 防止直接在UI线程中进行网络请求出现线程阻塞,导致应用程序无响应(ANR)

Dispatchers.IO:
用于执行I/O操作,如读写文件、访问数据库等。
这个调度器会尝试在后台线程池中执行I/O密集型任务,从而避免阻塞主线程

Dispatchers.Main:
用于在Android的主线程(UI线程)上执行协程。
这个调度器确保与UI相关的操作(如更新UI元素)在主线程上执行。
在非Android平台上(如桌面应用或纯Kotlin项目),Dispatchers.Main 可能不可用或行为不同。

Dispatchers.Default:
用于执行计算密集型任务。可用于执行网络请求,获取服务器数据
这个调度器使用共享的后台线程池来执行协程,从而优化CPU资源的利用。
它是默认的调度器,如果你没有为协程指定调度器,那么它将使用 Dispatchers.Default。

Dispatchers.Unconfined:
不绑定到任何特定的线程
协程在哪个线程上启动,它就会在那个线程上继续执行,直到遇到挂起点(如 suspend 函数调用)。
一旦协程挂起并恢复,它可能会在任何线程上继续执行,这取决于挂起函数的实现。

通常不建议在生产代码中使用 Dispatchers.Unconfined,因为它可能导致难以追踪的线程安全问题。
用法:

// 创建一个协程作用域(通常是在ViewModel、Activity或Fragment中)
val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)// 在协程作用域中启动一个协程
coroutineScope.launch(Dispatchers.IO) {// 执行I/O操作
}

2.1 定义请求回调结果的数据类

sealed 关键字
sealed 关键字用于定义一个密封类(sealed class),用于控制子类的个数,只接受子类在密封类的同一个文件中声明,或者作为密封类的嵌套类。

有助于改进when表达式,当使用密封类的时候,编译器会确保when表达式覆盖所有可能得子类,如果没有覆盖的话,则会出现报错的提醒,这有助于提高代码的健壮性和可维护性。

sealed class Result<out R> {data class Success<out T>(val data: T) : Result<T>()data class Error(val exception: Exception) : Result<Nothing>()
}

2.2 网络请求

为了防止主线程调用 makeLoginRequest 后出现阻塞界面情况。可以使用协程库中的 withContext() 函数将协程的执行操作移至其他线程,在其中执行耗时的网络请求操作

class LoginRepository(private val responseParser: LoginResponseParser) {private const val loginUrl = "https://example.com/login"suspend fun makeLoginRequest(jsonBody: String): Result<LoginResponse> {return withContext(Dispatchers.IO) {// Blocking network request codeval url = URL(loginUrl)(url.openConnection() as? HttpURLConnection)?.run {requestMethod = "POST"setRequestProperty("Content-Type", "application/json; utf-8")setRequestProperty("Accept", "application/json")doOutput = trueoutputStream.write(jsonBody.toByteArray())return Result.Success(responseParser.parse(inputStream))}return Result.Error(Exception("Cannot open HttpURLConnection"))}}
}

3、网络回调结构

假设请求回调的结构为:

{"success": true,"user": {"id": 123,"username": "exampleUser","email": "example@example.com"},"token": "some_jwt_token"}

为了适配并处理网络请求回调的数据,需要创建数据类,方便适配回调数据。

data class User(val id: Int,val username: String,val email: String
)data class LoginResponse(val success: Boolean,val user: User?,val token: String?
)

将网络请求返回的InoutStream通过LoginResponseParser 处理,读取返回的数据并进行处理,转为LoginResponse的数据。

import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReaderobject LoginResponseParser {private val gson = Gson()@Throws(JsonSyntaxException::class)fun parse(inputStream: InputStream): LoginResponse {return try {// 使用try-with-resources语句自动关闭BufferedReadergson.fromJson(BufferedReader(InputStreamReader(inputStream)).use {it.readText()}, LoginResponse::class.java)} catch (e: IOException) {// 处理IOException,例如记录日志或抛出运行时异常throw RuntimeException("Failed to read input stream", e)} catch (e: JsonSyntaxException) {// 处理JsonSyntaxException,例如记录日志或抛出运行时异常throw RuntimeException("Failed to parse JSON", e)}}
}

4、通过ViewModel处理网络请求数据

class LoginViewModel(private val loginRepository: LoginRepository
): ViewModel() {fun login(username: String, token: String) {viewModelScope.launch {val jsonBody = "{ username: \"$username\", token: \"$token\"}"val result = try {loginRepository.makeLoginRequest(jsonBody)} catch(e: Exception) {Result.Error(Exception("Network request failed"))}when (result) {is Result.Success<LoginResponse> -> // Happy pathelse -> Result.Error(Exception("reponse is error"))// Show error in UI}}}
}

想要了解更多协程相关的知识点,可以查看官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22662.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树形DP(树形背包+换根DP)

树形DP 没有上司的舞会 家常便饭了&#xff0c;写了好几遍&#xff0c;没啥好说的&#xff0c;正常独立集问题。 int head[B]; int cnt; struct node {int v,nxt; }e[B<<1]; void modify(int u,int v) {e[cnt].nxthead[u];e[cnt].vv;head[u]cnt; } int a[B]; int f[B]…

REACT--组件通信

组件之间如何进行通信&#xff1f; 组件通信 组件的通信主要借助props传递值 分为整体接收、解构接收 整体接收 import PropTypes from prop-types;//子组件 function Welcome(props){return (<div>hello Welcome,{props.count},{props.msg}</div>) }// 对 We…

【排序算法】六大比较类排序算法——插入排序、选择排序、冒泡排序、希尔排序、快速排序、归并排序【详解】

文章目录 六大比较类排序算法&#xff08;插入排序、选择排序、冒泡排序、希尔排序、快速排序、归并排序&#xff09;前言1. 插入排序算法描述代码示例算法分析 2. 选择排序算法描述优化代码示例算法分析 3. 冒泡排序算法描述代码示例算法分析与插入排序对比 4. 希尔排序算法描…

纠错检索增广生成论文

一、摘要 动机&#xff1a;RAG严重依赖于检索文档的相关性&#xff0c;如果检索出错&#xff0c;那么LLM的输出结果也会出现问题 解决方案&#xff1a;提出纠正性检索增强生成&#xff08;CRAG&#xff09;即设计一个轻量级的检索评估器&#xff0c;用来评估针对某个查询检索…

Java NIO与传统IO性能对比分析

Java NIO与传统IO性能对比分析 在Java中&#xff0c;I/O&#xff08;输入输出&#xff09;操作是开发中最常见的任务之一。传统的I/O方式基于阻塞模型&#xff0c;而Java NIO&#xff08;New I/O&#xff09;引入了非阻塞和基于通道&#xff08;Channel&#xff09;和缓冲区&a…

easelog(1)基础C++日志功能实现

EaseLog(1)基础C日志功能实现 Author: Once Day Date: 2025年2月22日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 注&#xff1a;本简易日志组件代码实现参考了Google …

Vue面试2

1.跨域问题以及如何解决跨域 跨域问题&#xff08;Cross-Origin Resource Sharing, CORS&#xff09;是指在浏览器中&#xff0c;当一个资源试图从一个不同的源请求另一个资源时所遇到的限制。这种限制是浏览器为了保护用户安全而实施的一种同源策略&#xff08;Same-origin p…

MongoDB应用设计调优

应用范式设计 什么是范式 数据库范式概念是数据库技术的基本理论&#xff0c;几乎是伴随着数据库软件产品的推出而产生的。在传统关系型数据库领域&#xff0c;应用开发中遵循范式是最基本的要求。但随着互联网行业的发展&#xff0c;NoSQL开始变得非常流行&#xff0c;在许多…

Mac安装配置Tomcat 8

一、官网下载 Index of /disthttps://archive.apache.org/dist/ 1、进入界面如下&#xff1a; 2、我们找到Tomcat文件夹并进入 3、找到Tomcat 8并打开 4、找到对应的版本打开 5、打开bin 6、找到“apache-tomcat-8.5.99.tar.gz”并下载 二、配置Tomcat 1、解压已经下载好的…

【论文精读】VLM-AD:通过视觉-语言模型监督实现端到端自动驾驶

论文地址&#xff1a; VLM-AD: End-to-End Autonomous Driving through Vision-Language Model Supervision 摘要 人类驾驶员依赖常识推理来应对复杂多变的真实世界驾驶场景。现有的端到端&#xff08;E2E&#xff09;自动驾驶&#xff08;AD&#xff09;模型通常被优化以模仿…

百度搜索,能否将DeepSeek变成“内功”?

最近&#xff0c;所有的云平台和主流APP都在努力接入DeepSeek。其中&#xff0c;搜索类APP与搜索引擎更是“战况激烈”。那么问题来了&#xff0c;接入DeepSeek已经变成了标准配置&#xff0c;到底应该如何做出差异化&#xff1f;接入DeepSeek这件事能不能实现11大于2的效果&am…

Flask实现高效日志记录模块

目录 一. 简介&#xff1a; 1. 为什么需要请求日志 二. 日志模块组成 1. 对应日志表创建&#xff08;包含日志记录的关键字段&#xff09; 2. 编写日志记录静态方法 3. 在Flask中捕获请求日志 4. 捕获异常并记录错误日志 5. 编写日志接口数据展示 6. 写入数据展…

25轻化工程研究生复试面试问题汇总 轻化工程专业知识问题很全! 轻化工程复试全流程攻略 轻化工程考研复试真题汇总

轻化工程复试心里没谱&#xff1f;学姐带你玩转面试准备&#xff01; 是不是总觉得老师会问些刁钻问题&#xff1f;别焦虑&#xff01;其实轻化工程复试套路就那些&#xff0c;看完这篇攻略直接掌握复试通关密码&#xff01;文中有重点面试题可直接背~ 目录 一、这些行为赶紧避…

查看已经安装的Python库,高效管理自己的Python开发环境

在日常的Python开发中&#xff0c;掌握如何管理和查看已经安装的库是非常重要的。这不仅能帮助你了解当前项目的依赖关系&#xff0c;还能避免出现版本冲突等问题。在这篇文章中&#xff0c;我们将详细介绍查看已安装Python库的方法&#xff0c;并提供一些实用的工具和技巧。 …

Selenium实战案例1:论文pdf自动下载

在上一篇文章中&#xff0c;我们介绍了Selenium的基础用法和一些常见技巧。今天&#xff0c;我们将通过中国科学&#xff1a;信息科学网站内当前目录论文下载这一实战案例来进一步展示Selenium的web自动化流程。 目录 中国科学&#xff1a;信息科学当期目录论文下载 1.网页内…

Visual Studio Code 2025 安装与高效配置教程

一、软件简介与下载 1. Visual Studio Code 是什么&#xff1f; Visual Studio Code&#xff08;简称VS Code&#xff09;是微软推出的免费开源代码编辑器&#xff0c;支持 智能代码补全、Git集成、插件扩展 等功能&#xff0c;适用于前端开发、Python、Java等多种编程场景。…

工业路由器和工业交换机,打造高效稳定的工业网络?

工业路由器和工业交换机各有千秋&#xff0c;但如何将它们完美结合&#xff0c;构建稳定高效的工业网络&#xff1f;答案就在这里&#xff01; 工业物联网&#xff08;IIoT&#xff09;是高效、稳定的工业网络成为智慧工厂、工业自动化和远程监控等场景的基础支撑。工业路由器…

DeepSeek 助力 Vue 开发:打造丝滑的二维码生成(QR Code)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

TSMaster【第七篇:千机百变——面板设计艺术】

武侠场景导入&#xff1a;唐门暗器阁的启示 江湖传言&#xff0c;唐门暗器之所以独步天下&#xff0c;全凭其「千机匣」中七十二种机关变化。TSMaster面板设计恰似打造暗器机关——控件如同飞镖、机簧、毒针&#xff0c;组合方式不同则威力迥异。昔日某新势力车型因仪表盘刷新…

提升 AI 服务的稳定性:Higress AI 网关的降级功能介绍

在使用 LLM 服务时&#xff0c;服务的稳定性和可用性至关重要。然而&#xff0c;由于网络问题、服务器故障或其他不可控因素&#xff0c;LLM 服务可能会暂时不可用。为了保障用户体验和业务连续性&#xff0c;Higress AI 网关提供了强大的模型降级和令牌降级功能。本文将介绍这…