当前位置: 首页 > wzjs >正文

发布网站的两种方法游仙移动网站建设

发布网站的两种方法,游仙移动网站建设,h5网站搭建,邯郸做网站哪儿好1. 什么是协程 协程(Coroutine)是轻量级的线程,支持挂起和恢复,从而避免阻塞线程。 2. 协程的优势 协程通过结构化并发和简洁的语法,显著提升了异步编程的效率与代码质量。 2.1 资源占用低(一个线程可运行多个协程)…

1. 什么是协程

协程(Coroutine)是轻量级的线程,支持挂起和恢复,从而避免阻塞线程。

在这里插入图片描述

2. 协程的优势

协程通过结构化并发和简洁的语法,显著提升了异步编程的效率与代码质量。

2.1 资源占用低(一个线程可运行多个协程)

传统多线程模型中,每个线程需要独立的系统资源(如内存栈),而协程共享线程资源。

  • 高效线程利用​​:通过调度器(如 Dispatchers.IO),一个线程池可同时处理数千个协程任务(如并发网络请求或文件读写)。
  • 减少上下文切换​​:协程挂起时不会阻塞线程,线程可立即执行其他协程任务,减少线程切换的性能损耗。

2.2 代码可读性强(顺序编写异步逻辑)

协程通过同步代码风格实现异步逻辑,彻底消除“回调地狱”。

  • 同步化表达:使用挂起函数(如 withContext、await())可将异步操作写成顺序执行的代码。
  • ​​结构化并发​​:通过 CoroutineScope 管理协程生命周期,自动取消子协程,避免内存泄漏。

3. 协程的核心组件

协程通过一组核心组件实现结构化并发和高效的任务管理。

3.1 ​​CoroutineScope(作用域)​

  • 管理协程的生命周期,确保协程在特定范围内启动和取消。
  • 通过结构化并发避免资源泄漏。
3.1.1 常见作用域​​:
  • lifecycleScope : 与 Lifecycle(如 Activity/Fragment)绑定,界面销毁时自动取消所有子协程。
  • viewModelScope​ : 与 ViewModel 绑定,ViewModel 销毁时自动取消协程,适合处理业务逻辑。

3.2 ​​CoroutineContext(上下文)​

定义协程的上下文信息,如线程调度器、协程名称、异常处理器等。

  • Job : 控制协程的生命周期(启动、取消、监控状态)
  • ​​Dispatcher​ : 指定协程运行的线程
  • CoroutineName : 为协程命名,便于调试

3.3 Dispatcher (调度器)

指定协程运行的线程

  • Dispatchers.Main​​ : 主线程,用于更新 UI 或执行轻量级操作。
    ​​注意​​:在非 Android 环境(如单元测试)中可能不存在。​​
  • Dispatchers.IO​​ : 适用于 IO 密集型任务(如网络请求、数据库读写、文件操作)。
    ​​底层机制​​:共享线程池,默认最小 64 线程。
  • Dispatchers.Default​​ : 适用于 CPU 密集型任务(如排序、计算、图像处理)。
    ​​底层机制​​:线程数与 CPU 核心数相同。​

3.4 ​​Job (作业)

3.4.1 Job (作业)

表示一个协程任务,不返回结果,通过 launch 创建。

val job = launch { /* ... */ }
job.start()    // 启动(默认自动启动)
job.cancel()   // 取消
job.join()     // 挂起当前协程,等待此 Job 完成
3.4.2 Deferred (异步结果)

Job 的子类,表示一个会返回结果的异步任务,通过 async 创建。

val deferred = async { fetchData() }  
val data = deferred.await() // 挂起协程直到结果就绪

4. 协程构建器

协程构建器是创建和启动协程的入口点,不同构建器适用于不同场景。

4.1 ​​launch:启动一个不返回结果的协程

启动一个不返回结果的协程,适用于“触发后无需等待结果”的任务(如日志上报、缓存清理)。

​特性

  • 返回 Job 对象,用于控制协程生命周期(取消、监控状态)。
  • 默认继承父协程的上下文(如作用域、调度器)。
// 在 ViewModel 中启动一个后台任务
fun startBackgroundTask() {viewModelScope.launch(Dispatchers.IO) {  cleanCache()    // 在 IO 线程执行清理操作log("Cache cleaned") // 完成后记录日志}// 无需等待结果,直接执行后续代码
}

4.2 ​​async:并发执行并获取结果​

启动一个返回结果的协程,适用于需要并行执行多个任务并汇总结果的场景。

特性​​:

  • 返回 Deferred 对象,通过 await() 挂起并获取结果。
  • 可通过 async 启动多个协程后统一等待结果,提升执行效率。

示例​​:并行请求多个接口并合并数据

viewModelScope.launch {// 同时发起两个网络请求val userDeferred = async(Dispatchers.IO) { fetchUser() }  val postsDeferred = async(Dispatchers.IO) { fetchPosts() }// 等待两个请求完成(总耗时取决于最慢的任务)val user = userDeferred.await()  val posts = postsDeferred.await()// 合并结果并更新 UIshowUserProfile(user, posts)
}

4.3 ​​runBlocking:在阻塞代码中启动协程​

阻塞当前线程,直到其内部的协程执行完毕。

​​主要用于测试​​,或在非协程环境中临时调用挂起函数。

示例​​:在单元测试中测试协程逻辑

@Test
fun testFetchData() = runBlocking {  // 阻塞当前线程,等待协程完成val data = fetchData() // 直接调用挂起函数assertEquals(expectedData, data)
}

应避免在主线程使用 runBlocking,因为会阻塞主线程 !

5. 挂起函数

挂起函数(Suspending Function)是协程的核心特性之一,允许协程在非阻塞的前提下暂停和恢复执行。挂起函数只能在协程或其他挂起函数中调用,适用于需要等待异步操作完成的场景。

5.1 ​​delay():协程的“非阻塞休眠”​

delay() 会暂停协程的执行指定时间(单位:毫秒),期间不会阻塞线程,线程可执行其他任务。

5.1.1 与 Thread.sleep() 的区别​​:
delay()Thread.sleep()
挂起协程,释放线程资源阻塞线程,线程无法执行其他任务
只能在协程或挂起函数中调用可在任何线程中调用
viewModelScope.launch {repeat(10) {  delay(1000)       // 每隔 1 秒执行一次,不阻塞主线程  updateCounter(it)  }  
}  

5.2 ​​withContext():灵活的线程切换​

在指定协程上下文(如 Dispatcher)中执行代码块,完成后自动恢复原上下文。替代传统回调或 Handler,简化线程切换逻辑。

suspend fun loadData() {  // 在 IO 线程执行网络请求  val data = withContext(Dispatchers.IO) {  api.fetchData()  }  // 自动切回调用方的上下文(如 Main 线程)  updateUI(data)  
}  
5.2.1 与 async 的区别​
  • withContext:直接返回结果,适用于单次切换线程的串行任务。
  • async:返回 Deferred,适用于并行任务。

避免嵌套多层 withContext,可用 async 替代以提升并发效率。

5.3 await():安全获取异步结果​

挂起协程,等待 Deferred 任务完成并返回结果。若 Deferred 任务出现异常,await() 会抛出该异常。

5.3.1 示例​​:并行任务与结果合并
viewModelScope.launch {  val task1 = async(Dispatchers.IO) { fetchDataA() }  val task2 = async(Dispatchers.IO) { fetchDataB() }  // 同时等待两个任务完成  val combinedData = combineData(task1.await(), task2.await())  
}  
5.3.2 await()怎么处理异常

使用 try-catch 捕获 await() 的异常:

val deferred = async { /* 可能抛出异常的代码 */ }  
try {  val result = deferred.await()  
} catch (e: Exception) {  handleError(e)  
}  

若需取消任务,调用 deferred.cancel()

5.3.3 协程是否存活

通过 coroutineContext.isActive 检查协程是否存活,可以及时终止无效操作

suspend fun heavyCalculation() {  withContext(Dispatchers.Default) {  for (i in 0..100000) {  if (!isActive) return@withContext // 检查协程是否被取消  // 执行计算  }  }  
}  

6. 协程的异常处理机制

6.1 异常传播机制

默认规则​​:

  • 子协程异常会向上传播​​:当子协程抛出未捕获的异常时,父协程会立即取消,进而取消所有其他子协程。
  • 兄弟协程受影响​​:若子协程 A 抛出异常,其兄弟协程 B 也会被取消,即使 B 仍在执行中。

示例​​:未捕获异常导致父协程取消

viewModelScope.launch {// 子协程 1launch {delay(100)throw IOException("网络请求失败") // 未捕获异常}// 子协程 2(会被父协程取消)launch {repeat(10) {delay(200)log("子任务执行中") // 仅执行 1 次后父协程取消}}
}

6.2 捕获异常的方式

6.2.1 方式 1:try-catch 块

在协程内部直接捕获异常,适用于同步代码逻辑。

viewModelScope.launch {try {fetchData() // 可能抛出异常的挂起函数} catch (e: IOException) {showError("网络异常: ${e.message}")}
}
6.2.2 方式 2:CoroutineExceptionHandler

全局异常处理器,用于捕获未通过 try-catch 处理的异常。

定义异常处理器

val exceptionHandler = CoroutineExceptionHandler { _, throwable ->log("未捕获异常: ${throwable.message}")showErrorToast() // 例如弹出 Toast
}

附加到协程上下文

viewModelScope.launch(exceptionHandler) {  launch { throw IOException() } // 异常会被 exceptionHandler 捕获
}

仅在根协程(直接通过 launch 或 async 创建的顶层协程)中生效。

6.3 隔离异常:SupervisorJob

阻止子协程的异常传播到父协程,避免“一颗老鼠屎坏了一锅粥”。常用于独立任务场景(如同时发起多个不相关的网络请求)。

  • 子协程的失败不会影响其他子协程。
  • 父协程仍会等待所有子协程完成(除非显式取消)。
6.3.1 ​​通过 SupervisorJob() 创建作用域​​
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
scope.launch { throw Exception() } // 不影响其他子协程
scope.launch { delay(1000) }       // 正常执行
6.3.2 在现有作用域中使用 supervisorScope
viewModelScope.launch {supervisorScope {launch { throw IOException() } // 仅自身失败launch { delay(1000) }          // 继续执行}
}

6.4 自定义异常处理策略

可以根据业务需求设计容错逻辑,例如:

​​- 重试机制​​:在捕获异常后自动重试任务。
​​- 回退操作​​:失败时返回默认值或缓存数据。

6.4.1 示例:网络请求重试​
suspend fun fetchDataWithRetry(retries: Int = 3): Data {repeat(retries) { attempt ->try {return api.fetchData()} catch (e: IOException) {if (attempt == retries - 1) throw e // 最后一次重试仍失败则抛出异常delay(1000 * (attempt + 1))         // 延迟后重试(指数退避)}}throw IllegalStateException("Unreachable")
}

6.5 协程异常的最佳实践

6.5.1 明确异常边界​​
  • 在协程根节点或关键入口处统一处理异常(如使用 CoroutineExceptionHandler)。
  • 避免在底层函数中静默吞没异常(如 catch 后不处理)。
6.5.2 区分取消与异常
  • 使用 isActive 检查协程状态,及时终止无效任务。
  • 通过 ensureActive() 快速失败
public fun Job.ensureActive(): Unit {if (!isActive) throw getCancellationException()
}
6.5.3 ​​谨慎使用 SupervisorJob

仅当子协程完全独立时使用,避免隐藏潜在问题。


文章转载自:

http://siObylZY.gbcxb.cn
http://GHhBvbkg.gbcxb.cn
http://pQHjGXT8.gbcxb.cn
http://l5a4DzdQ.gbcxb.cn
http://l5tRduvs.gbcxb.cn
http://Lce9Occ0.gbcxb.cn
http://Ukhtav71.gbcxb.cn
http://0JYNye5J.gbcxb.cn
http://RfmF2IJa.gbcxb.cn
http://QDigUES0.gbcxb.cn
http://3R4SrLE6.gbcxb.cn
http://GnARcSsx.gbcxb.cn
http://Sp1iiyLN.gbcxb.cn
http://LlKdl07k.gbcxb.cn
http://nLfNzt9R.gbcxb.cn
http://iZkMSvDb.gbcxb.cn
http://OmjaDgob.gbcxb.cn
http://5811r7G2.gbcxb.cn
http://1Pyp6uTB.gbcxb.cn
http://85fe3EpR.gbcxb.cn
http://ET78EnHL.gbcxb.cn
http://0qkzDTxx.gbcxb.cn
http://biVbRPtU.gbcxb.cn
http://jbJUg19v.gbcxb.cn
http://zdHxUqkk.gbcxb.cn
http://mSo9KpHj.gbcxb.cn
http://ieOd9Hf3.gbcxb.cn
http://T45MOvLJ.gbcxb.cn
http://aIK9eWee.gbcxb.cn
http://RHy7Rnpx.gbcxb.cn
http://www.dtcms.com/wzjs/704563.html

相关文章:

  • 化工建设信息网站合肥网站建设渠道
  • 国外 设计师 网站深圳方维网站建设
  • 网站空间哪里便宜wordpress手机上传图片失败
  • 长治哪家公司做网站好ps网页设计论文
  • 网站建设便宜公司买虚机送网站建设
  • 怎么自己做网站app上海个体工商户如何注册
  • 甜点网站要怎么做凡客诚品是什么平台
  • 番禺微网站建设成都市城乡和住房建设局
  • wordpress 网站域名域名申请成功后怎么做网站
  • 服务器做网站上传快好还是下载快好注销网站 取消接入
  • 德州加盟网站建设wordpress名片模板下载
  • wordpress建立手机网站竞价网站制作
  • 公司高端网站设计公司长沙做电商网站设计
  • 设计之家官方网站内蒙古建设协会网站
  • 郑州的做网站公司哪家好广州番禺区邮政编码
  • 网站怎么做推广和优化广州建站模板厂家
  • 广东省交通建设监理检测协会网站网赌网站怎么建设
  • 网站开发设计工程师岗位职责企业vi设计公司有哪些
  • 成都网站建设网站制作公司来个黑黑的网站
  • 关于英文网站建设的请示静态网站添加到织梦
  • 如何做一张图片的网站西安进一步优化近期防疫措施
  • 山东君天建设工程有限公司网站用火车采集器发布信息时 如何获取网站栏目id
  • 品牌商城网站制作直通车怎么开效果最佳
  • 做网站公司不给源代码保定seo博客
  • 温州做网站掌熊号网站的空间价格
  • 卖水果网站建设的策划书网站建设咨询电话
  • 自贡网站设计请拿笔记记下新域名
  • 有限公司网站建设 互成网络地址 四川汕头网站制作流程
  • 安装wordpress建站程序企业电子商务网站
  • intitle 无线网站制作北京网页制作专业服务