android 协程基础(二)

kotlin协程-Android实战 都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 PDF(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。Java语言与原理;大厂,小厂。Android面试先看你熟不熟悉Java语言高级UI与自定义view。 阅读详情

协程构建器

launch和async构建器

launch

返回一个Job并且不会附带任何结果值

async

返回一个Deferred,Deferred是一个Job,可以使用await()在一个延期的值上得到它的最终结果
eg:通过await()来获取结果

 GlobalScope.launch{
            val job1 = launch {
                delay(200)
                println("job1")
            }
            println("job 测试顺序1")

            val job2 = async {
                delay(300)
                println("job2")
                "job2 result"
            }
            println("job 测试顺序2")

            println(job2.await())

            println("job 测试顺序3")

        }
        println("job 测试顺序0")
job 测试顺序0
job 测试顺序1
job 测试顺序2
job1
job2
job2 result
job 测试顺序3

join

join()方法可以在一个作业中中等待另一个作业结束后再进行其他操作,将上面代码改变下:

 GlobalScope.launch{
            val job1 = launch {
                delay(1000)
                println("job1")
            }
           
            println("job 测试顺序1")

            val job2 = async {
                delay(100)
                println("job2")
                "job2 result"
            }
            println("job 测试顺序2")

            println(job2.await())

            println("job 测试顺序3")

        }
        println("job 测试顺序0")

结果(未使用join方法):发现挂起时间短的先执行

2021-08-15 15:45:25.547 5604-5604/com.hujin.wan I/System.out: job 测试顺序0
2021-08-15 15:45:25.548 5604-5638/com.hujin.wan I/System.out: job 测试顺序1
2021-08-15 15:45:25.550 5604-5638/com.hujin.wan I/System.out: job 测试顺序2
2021-08-15 15:45:25.657 5604-5638/com.hujin.wan I/System.out: job2
2021-08-15 15:45:25.657 5604-5638/com.hujin.wan I/System.out: job2 result
2021-08-15 15:45:25.657 5604-5638/com.hujin.wan I/System.out: job 测试顺序3
2021-08-15 15:45:26.557 5604-5637/com.hujin.wan I/System.out: job1

如果需要job按照顺序执行的话,比如先执行job1,再执行job2或者job3:
eg:job1执行join方法

 GlobalScope.launch{
            val job1 = launch {
                delay(1000)
                println("job1")
            }
            job1.join()
            println("job 测试顺序1")

            val job2 = async {
                delay(100)
                println("job2")
                "job2 result"
            }

            val job3 = launch {
                delay(100)
                println("job3")
            }
            println("job 测试顺序2")

            println(job2.await())

            println("job 测试顺序3")

        }
        println("job 测试顺序0")

结果:job1先执行,再执行job2和job3

2021-08-15 15:49:00.647 5730-5730/com.hujin.wan I/System.out: job 测试顺序0
2021-08-15 15:49:01.653 5730-5764/com.hujin.wan I/System.out: job1
2021-08-15 15:49:01.655 5730-5764/com.hujin.wan I/System.out: job 测试顺序1
2021-08-15 15:49:01.655 5730-5764/com.hujin.wan I/System.out: job 测试顺序2
2021-08-15 15:49:01.760 5730-5764/com.hujin.wan I/System.out: job3
2021-08-15 15:49:01.760 5730-5763/com.hujin.wan I/System.out: job2
2021-08-15 15:49:01.761 5730-5763/com.hujin.wan I/System.out: job2 result
2021-08-15 15:49:01.761 5730-5763/com.hujin.wan I/System.out: job 测试顺序3

eg:使用async/await来代替join,到达同样的效果

 GlobalScope.launch{
            val job1 = async {
                delay(1000)
                println("job1")
            }
            job1.await()
            println("job 测试顺序1")

            val job2 = async {
                delay(100)
                println("job2")
                "job2 result"
            }

            val job3 = launch {
                delay(100)
                println("job3")
            }
            println("job 测试顺序2")

            println(job2.await())

            println("job 测试顺序3")

        }
        println("job 测试顺序0")

结果:到达同样的效果

2021-08-15 15:54:10.557 5913-5913/com.hujin.wan I/System.out: job 测试顺序0
2021-08-15 15:54:11.565 5913-5946/com.hujin.wan I/System.out: job1
2021-08-15 15:54:11.566 5913-5946/com.hujin.wan I/System.out: job 测试顺序1
2021-08-15 15:54:11.569 5913-5946/com.hujin.wan I/System.out: job 测试顺序2
2021-08-15 15:54:11.673 5913-5945/com.hujin.wan I/System.out: job3
2021-08-15 15:54:11.673 5913-5945/com.hujin.wan I/System.out: job2
2021-08-15 15:54:11.673 5913-5945/com.hujin.wan I/System.out: job2 result
2021-08-15 15:54:11.673 5913-5945/com.hujin.wan I/System.out: job 测试顺序3

组合并发

先看一场景,2个结果的相加:

 private fun testCombination() {
        GlobalScope.launch {
            val time = measureTimeMillis {
                val one = doOne()
                val two = doTwo()
                println("the result : ${one + two}")
            }
            println("the pay time $time")
        }
    }


    suspend fun doOne():Int{
        delay(1000)
        return 15
    }

    suspend fun doTwo():Int{
        delay(1000)
        return 20
    }
2021-08-15 16:52:35.496 6575-6604/com.hujin.wan I/System.out: the result : 35
2021-08-15 16:52:35.496 6575-6604/com.hujin.wan I/System.out: the pay time 2008

你会发现这两个结果内部是同步的,消耗时间是两个方法总时间,改造下:

 private fun testCombination() {
        GlobalScope.launch {
            val time = measureTimeMillis {
                val one = async { doOne() }
                val two = async { doOne() }
                println("the result : ${one.await() + two.await()}")
            }
            println("the pay time $time")
        }
    }

结果:

2021-08-15 16:57:07.113 6725-6758/com.hujin.wan I/System.out: the result : 30
2021-08-15 16:57:07.113 6725-6758/com.hujin.wan I/System.out: the pay time 1016

协程的启动模式

先看下launch的代码:

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}

在我们协程启动的时候,可以设置一个启动模式,默认是CoroutineStart.DEFAULT。
启动模式是指定协程在启动后是怎样的一个行为,一共有四种启动模式:

DEFAULT

协程创建后,立即开始调度,在调度前如果协程被取消,其将直接进入取消的响应状态

 private  fun testStartMode(){
        runBlocking {
            val job = launch(start = CoroutineStart.DEFAULT) {
                println("job 被挂起")
                delay(10000)
                //下面这句不会被执行
                println("job finished")
            }
            delay(1000)
            job.cancel()
        }
    }
  private  fun testStartMode(){
        val job = GlobalScope.launch(start = CoroutineStart.DEFAULT) {
            //下面这句可能不会被执行
            println("job finished")
        }
        job.cancel()
        println("job cancel")
    }

上面两种案例是不同的,一个是协程的执行期间被取消,第二个是调度前被取消的,可对照下面ATOMIC。

ATOMIC

协程创建后,立即开始调度(不代表立即执行),协程执行到第一个挂起点之前不会响应取消(原子性)

 private  fun testStartMode(){
        val job = GlobalScope.launch(start = CoroutineStart.ATOMIC) {
            //下面这句是会执行的
            println("job finished")
        }
        job.cancel()
        println("job cancel")
    }

结果:

job cancel
job finished"
    private  fun testStartMode(){
        val job = GlobalScope.launch(Dispatchers.Default,start = CoroutineStart.ATOMIC) {
          
            println("job start")
            delay(10)
            //这句不会执行
            println("job finished")

        }
        job.cancel()
        println("job cancel")
    }

结果:

job cancel
job start

LAZY

只有在需要的时候(调用协程start、join、await等)才会开始调度,如果调度前被取消,就不会执行,而是直接进入异常结束状态.一般先是用来定义好的。
eg:需要调用join才会执行协程体的内容,调用cancelAndJoin是无法执行的

    private  fun testStartMode(){
        runBlocking {
            val job = GlobalScope.launch(Dispatchers.Default,start = CoroutineStart.LAZY) {
                //下面这句可能不会被执行
                println("job start")
//                delay(100)
//                println("job finished")

            }
            job.join()
            println("job cancel")
        }

    }

UNDISPATCHED

协程创建后立即在当前函数调用栈中执行,直到遇到第一个真正挂起的点.

协程的作用域构建器

runBlocking与coroutineScope

  • runBlocking是常规函数,而coroutineScope是挂起函数
  • 都会等待其协程体以及所有子协程结束,区别在于runBlocking方法会阻塞当前线程来等待,而coroutineScope只是挂起,会释放底层线程去干其他的

runBlocking 的例子,会阻塞等待延迟结束

 private  fun testStartCoroutine(){
        runBlocking {
            delay(1000)
            Log.e("TAG","runBlocking[当前线程为:${Thread.currentThread().name}]")

        }
        Log.e("TAG","1.runBlocking[当前线程为:${Thread.currentThread().name}]")

    }
2021-08-29 16:29:50.756 22304-22304/com.hujin.wan E/TAG: runBlocking[当前线程为:main]
2021-08-29 16:29:50.757 22304-22304/com.hujin.wan E/TAG: 1.runBlocking[当前线程为:main]

CoroutineScope 的例子,会挂起执行后面逻辑

 private  fun testStartCoroutine(){
        CoroutineScope(Dispatchers.Main).launch {
            delay(1000)
            Log.e("TAG","CoroutineScope[当前线程为:${Thread.currentThread().name}]")

        }
        Log.e("TAG","1.CoroutineScope[当前线程为:${Thread.currentThread().name}]")

    }

2021-08-29 16:40:16.385 22504-22504/com.hujin.wan E/TAG: 1.CoroutineScope[当前线程为:main]
2021-08-29 16:40:18.029 22504-22504/com.hujin.wan E/TAG: CoroutineScope[当前线程为:main]

coroutineScope与supervisorScope

  • coroutineScope 一个协程失败了,所以其他兄弟协程也会被取消。内部的异常会向上传播,子协程未捕获的异常会向上传递给父协程,任何一个子协程异常退出,会导致整体的退出。
  • supervisorScope 一个协程失败了,不会影响其他兄弟协程。内部的异常不会向上传播。
 runBlocking {
                supervisorScope {
                    val child1 = launch {
                        delay(400)
                        println("Child 1 is finished")
                    }
                    val child2 = launch {
                        println("Child 2 is sleeping")
                        delay(200)
                        println("Child 2 throws an exception")
                        throw AssertionError()
                    }
                }

            }

Job

Job对象

对于每一个创建的协程(通过launch或者async),会返回一个Job实例,是协程的唯一标示,并负责管理协程的生命周期。
一个任务可以包含一系列状态:新创建(New)、活跃(Active)、完成中(Completing)、已完成(Completed)、取消中(Cancelling)和已取消(Cancelled)。可以通过Job来访问这些熟悉。

  private fun testJob() {
        val job = GlobalScope.launch {

        }
        val active = job.isActive
        val cancelled = job.isCancelled
        val completed = job.isCompleted
    }

Job的生命周期

在这里插入图片描述
如果协程处于活跃状态,在运行出错或者调用job.cancel()都会将当前任务置为取消中(Cancelling)状态(isActive = false,isCancelled = true)。当所以的子协程都完成后,协程会进入已取消(Cancelled)状态,此时isCompleted = true。

协程的取消

几个基本情况:

  • 取消作用域会取消它的子协程
  • 被取消的子协程并不会影响其余兄弟协程
  • 协程通过抛出一个特殊的异常CancellationException来处理取消操作。(不会真的抛错)
  • 所以coroutines中的挂起函数都是可以取消的。eg:withContext、delay等

子协程独立情景

 runBlocking {
            val request = launch {
                //job1 使用 GlobalScope 来启动
                GlobalScope.launch {
                    println("tag-test job1 execute   thread:"+ Thread.currentThread().name)
                    delay(1000)
                    println("tag-test job1 is finished   thread:"+ Thread.currentThread().name)
                }

                //job2 继承了父协程的上下文
                launch {
                    delay(100)
                    println("tag-test job2 execute   thread:"+ Thread.currentThread().name)
                    delay(1000)
                    println("tag-test job2 finished   thread:"+ Thread.currentThread().name)

                }
            }
            delay(500)
            request.cancel()
            delay(1000)
            println("tag-test all is  finished   thread:"+ Thread.currentThread().name)
        }

运行结果:job1是被独立出去了,即使父协程已经取消了。

job1 execute   thread:DefaultDispatcher-worker-4
job2 execute   thread:main
job1 is finished   thread:DefaultDispatcher-worker-4
all is  finished   thread:main

作用域取消

runBlocking {
            val request = launch {
                repeat(3) { i ->
                    launch {
                        println("coroutine $i is start")
                        delay((i + 1) * 200L)
                        println("coroutine $i is done")
                    }
                }
            }
            delay(300)
            request.cancel()
            println("coroutine request is done")
        }

结果:作用域取消了子协程

coroutine 0 is start
coroutine 1 is start
coroutine 2 is start
coroutine 0 is done
coroutine request is done

cpu密集型取消

先看一种,cpu密集型取消不成功的情况,直接调用job.cancle()方法不会取消:

 runBlocking {
            val startTime = System.currentTimeMillis()
            val job = launch(Dispatchers.Default) {
                var nextPrintTime = startTime
                var i = 0
                while (i < 5){
                    if(System.currentTimeMillis() >= nextPrintTime){
                        println("job: i am sleeping ${i++}...")
                        nextPrintTime+=500
                    }
                }
            }
            delay(1000)
            println("main : i am tried of waiting!")
            job.cancelAndJoin()
            println("main: now i can quit")
        }

测试结果:无法被取消

job: i am sleeping 0...
job: i am sleeping 1...
job:i am sleeping 2...
i am tried of waiting!
job: i am sleeping 3...
job: i am sleeping 4...
main: now i can quit

正确的退出方式,应该通过job的生命周期来退出cpu的计算逻辑,在调用cancle方法后,isActive会置为false,所以改动如下:

runBlocking {
            val startTime = System.currentTimeMillis()
            val job = launch(Dispatchers.Default) {
                var nextPrintTime = startTime
                var i = 0
                while (i < 5 && isActive){
                    if(System.currentTimeMillis() >= nextPrintTime){
                        println("job: i am sleeping ${i++}...")
                        nextPrintTime+=500
                    }
                }
            }
            delay(1000)
            println("main : i am tried of waiting!")
            job.cancelAndJoin()
            println("main: now i can quit")
        }

或者利用ensureActive()方法,效果一样的。

 runBlocking {
            val startTime = System.currentTimeMillis()
            val job = launch(Dispatchers.Default) {
                var nextPrintTime = startTime
                var i = 0
                while (i < 5 ){
                    ensureActive()
                    if(System.currentTimeMillis() >= nextPrintTime){
                        println("job: i am sleeping ${i++}...")
                        nextPrintTime+=500
                    }
                }
            }
            delay(1000)
            println("main : i am tried of waiting!")
            job.cancelAndJoin()
            println("main: now i can quit")
        }

结果:成功取消,退出while循环

job: i am sleeping 0...
job: i am sleeping 1...
job:i am sleeping 2...
i am tried of waiting!
main: now i can quit

还可以调用yield()方法,这个会让出cpu的调度。

在finally中释放资源

在协程被取消的时候抛出CancellationException 异常,可以在结构体里添加try{...}finally{...}中执行终结动作。

val job = launch {
                try {
                    repeat(1000) { i ->
                        println("job : i am sleeping $i")
                        delay(400)
                    }
                } finally {
                    println("job: i am running finally")
                }

            }
            delay(2000L)
            println("main: i am tired of waiting!")
            job.cancelAndJoin()
            println("main: now i can quit")

测试结果:

job : i am sleeping 0
job : i am sleeping 1
job : i am sleeping 2
job : i am sleeping 3
job : i am sleeping 4
main: i am tired of waiting!
job: i am running finally
main: now i can quit

不能被取消的任务

在结构体中的try-finally中,再使用挂起操作,是不能被取消的。eg:

 runBlocking {
            val job = launch {

                try {
                    repeat(1000) { i ->
                        println("job: i am sleeping $i...")
                        delay(500L)
                    }
                } finally {
                    withContext(NonCancellable) {
                        println("job: i am running finally")
                        delay(5000)
                        println("job: and i have just delayed for 1 sec because i am non-cancellable")
                    }
                }
            }
            delay(1400)
            println("main: i am tired of waiting")
            job.cancelAndJoin()
            println("main: Now i can quit")
        }
2021-09-13 22:32:04.842 11979-11979/com.hujin.wan I/System.out: job: i am sleeping 0...
2021-09-13 22:32:05.345 11979-11979/com.hujin.wan I/System.out: job: i am sleeping 1...
2021-09-13 22:32:05.846 11979-11979/com.hujin.wan I/System.out: job: i am sleeping 2...
2021-09-13 22:32:06.244 11979-11979/com.hujin.wan I/System.out: main: i am tired of waiting
2021-09-13 22:32:06.247 11979-11979/com.hujin.wan I/System.out: job: i am running finally
2021-09-13 22:32:11.249 11979-11979/com.hujin.wan I/System.out: job: and i have just delayed for 1 sec because i am non-cancellable
2021-09-13 22:32:11.249 11979-11979/com.hujin.wan I/System.out: main: Now i can quit

超时

可以使用withTimeout或者withTimeoutOrNull来对一个可能会超时的协程进行处理, withTimeoutOrNull 通过返回 null 来进行超时操作,从而替代抛出一个异常:

launch {
                withTimeout(1300L){
                    repeat(10000){i->
                        println("i am sleeping $i ...")
                        delay(500)
                    }
                }
            }
android java协程,Android协程——入门 一、如何使用协程1.1 添加依赖implementation'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'implementation'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0'1.2 使用协程Coroutine在kotlinx.coroutines包中,你可以使用lau... 阅读详情

相关推荐

Vivaldi天线HFSS建模实战:从参数化曲线到辐射优化的完整流程

本文详细介绍了Vivaldi天线在HFSS中的建模与优化全流程,涵盖参数化曲线绘制、馈电系统设计及性能验证等关键步骤。通过实战案例分享,帮助工程师掌握超宽带天线的HFSS建模技巧,提升雷达探测和通信系统设计效率。重点解析了指数渐变曲线建模、微带馈电优化等核心技术要点。

weixin_29228781的博客 273

Android Kotlin之Coroutine(协程)详解

协程Coroutine是一种并发设计模式,您可以在 Android 平台上(Kotlin)使用它来简化异步执行的代码。在 Android Kotlin 上,协程Coroutine有助于管理长时间运行的任务,如果管理不当,这些任务可能会阻塞主线程并导致应用无响应。协程可以类似于RxJava那样,做到异步任务同步化,避免可能出现的回调地狱。同时,通过关键字来标识函数,称为挂起函数,该函数,只能在协程或其他的suspend函数中执行,从而保证主线程的安全。下面,我们先写个简单协程。协程多了2个状态。

蜗牛快跑 6575

FPGA实现Gardner环定时同步:Verilog代码与Testbench实战解析

本文深入解析了在FPGA上实现Gardner环定时同步的完整过程,详细阐述了其非数据辅助的定时误差检测原理。通过Verilog代码实战,展示了内插滤波器、定时误差检测器、环路滤波器和数控振荡器等核心模块的设计,并提供了完整的Testbench验证方法,帮助开发者解决数字通信系统中的时钟同步难题。

gpt4scribbler的博客 574

Android Deferred Object 项目常见问题解决方案

Android Deferred Object 项目常见问题解决方案 项目基础介绍 Android Deferred Object 是一个实现了 Deferred Object 模式的 Android 库,类似于 jQuery 中的 Deferred Object。该项目的主要目的是提供一种链式调用的方式,用于处理异步操作的成功、失败和进度通知。通过使用这个库,开发者可以更方便地管理异步任务的回调...

gitblog_00128的博客 665

【阿里云大模型高级工程师ACP习题集】2.4 自动化评测答疑机器人的表现(⭐️⭐️⭐️ 重点章节!!!)

【摘要】这是我精心整理出对应的习题集,里面足足有 30 道题目,从基础概念到深度拓展,全方位覆盖章节重点、难点。不管你是想检验自己的学习成果,还是想针对薄弱环节进行强化训练,它都能完美适配!

davidkorhenn的博客 2477

Windows本地部署Qwen3-14B实战指南:Ollama+Open WebUI零Docker方案

大语言模型本地部署是AI工程化落地的关键环节,其核心在于推理框架兼容性、硬件加速适配性与端到端稳定性。Ollama作为轻量级模型运行时,原生支持Windows DirectML与CUDA,规避了Docker/WSL2虚拟化开销和llama.cpp编译风险;Qwen3-14B则凭借128K上下文、Tool Calling原生支持及中文长文本结构化能力,成为政务、金融等场景首选。本文聚焦Windows平台真实约束——显存阈值、驱动版本匹配、路径编码兼容、离线知识库集成(RAG)等工程细节,提供经63台Windo

weixin_32136203的博客 412

Android Deferred Object 使用教程

Android Deferred Object 使用教程 项目介绍 Android Deferred Object 是一个用于处理异步操作的开源库,它基于 jQuery 的 Deferred 对象设计,旨在简化 Android 开发中的异步编程。该库提供了一种优雅的方式来管理异步任务,使得代码更加清晰和易于维护。 项目快速启动 添加依赖 首先,在你的 build.gradle 文件中添加以下依赖:...

gitblog_00233的博客 1022

进阶06:C#连接TwinCAT 3使用ADS通讯

本文介绍了使用C#通过ADS协议与倍福TwinCAT3 PLC通讯的实现方法。主要内容包括:1)在两台电脑上安装TwinCAT3开发环境并建立网络连接;2)在TwinCAT中定义变量和结构体;3)使用C# Winform开发界面,通过TwinCAT.Ads.dll实现读写功能;4)实现主动读取和通知两种数据获取方式。详细说明了连接建立、变量定义、读写操作及事件通知的实现代码。该方案实现了对PLC寄存器数据的实时监控和操作,为工业控制系统的开发提供了参考。

weixin_38637405的博客 3688

Android Kotlin 协程详解

Kotlin 协程是 Android 异步编程的革命性工具,通过轻量级、结构化并发和响应式编程,极大提升了代码的可读性和可维护性。掌握协程的基础、进阶技巧和最佳实践,能够显著提高开发效率,减少内存泄漏和线程管理问题。建议结合官方文档和实际项目不断实践,逐步深入理解协程的核心原理和应用场景。

ZLGSPACE的博客 3377

BLDC&PMSM电机控制器硬件设计工程(三)控制器驱动芯片方案

在汽车电机控制系统中,栅极驱动IC扮演着至关重要的角色。它作为主控MCU与功率开关管(MOSFET/IGBT)之间的桥梁,将微弱的PWM信号放大为足以快速、可靠驱动功率管的强信号。本文将深入解析英飞凌、TI和NXP的车规级栅极驱动方案,重点关注半桥和单侧驱动IC。1)为什么需要栅极驱动器?栅极驱动器是低压控制器和高压电路之间的缓冲电路,用于放大控制器的控制信号,从而实现功率器件更有效的导通和关断。栅极驱动器的作用总结如下:1.将控制器的低压信号转化为更高电压的驱动信号,以实现功率器件稳定导通和关断。

小幽余生不加糖 491

Day 01: 与Python的第一次亲密接触

环境搭建 、第一个程序 Hello, World!、以及Python之禅 (The Zen of Python) 的解读。

杨小扩的博客 220

Kotlin 协程 supervisorScope {} 运行崩溃解决

简单介绍函数,它用于创建一个使用了 SupervisorJob 的 coroutineScope,该作用域的特点:抛出的异常,不会 连锁取消 同级协程和父协程。看过很多文档的使用,我照抄一摸一样的代码,运行就崩溃,最后找到了解决方法,应该是kotlin版本更新做过改动,当前我使用的是。

Lan_Se_Tian_Ma的博客 1074

第51节:cesium 范围查询(含源码+视频)

cesium 范围查询

qq_29384639的博客 1495

Kotlin协程(二)之——在Android当中应用,android应用开发基础教材巫湘林

简单介绍 初步印象 在 Android Jetpack 中的 lifecycle、LiveData 和 ViewModel 已经集成了快速使用协程的方法 基本概念 viewModelScope 是预定义的 CoroutineScope,包含在 ViewModel KTX 扩展中 CoroutineScope 会跟踪它使用 launch 或 async 创建的所有协程,与调度器不同,CoroutineScope 不运行协程 Job是协程的句柄,使用 launch 或 async 创建的每个协程.

m0_65511948的博客 760

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Android学习总结之kotlin协程面试篇

kotlin协程的面试题讲解

2301_80329517的博客 3977

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Android Kotlin 协程(coroutine )入门篇

ps:文章会很长 协同程序(coroutine)实在是太好用了,所以我们来学习吧!

我怀里的猫的博客 9468

Kotlin协程(二)之——在Android当中应用

光有这些思路和搞懂单个知识的应用是还远远不够的,在Android开源框架设计思想中的知识点还是比较多的,想要搞懂还得学会整理和规划:我们常见的**Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、IOC依赖注入框架、最近架构组件Jetpack等等Android第三方开源框架,**这些都是属于Android开源框架设计思想的。如下图所示:这位阿里P8大佬针对以上知识点,熬夜整理出了一本长达1042页的完整版如何解读开源框架设计思想。

2401_84132479的博客 807

Android开发进阶:深入理解Kotlin协程

协程(Coroutine)是一种轻量级的线程管理框架,它通过**挂起(Suspend)和恢复(Resume)**的机制实现异步代码的同步化编写。资源消耗低:单线程可运行多个协程代码可读性强:避免回调地狱(Callback Hell)生命周期可控:与组件(如Activity、ViewModel)绑定Kotlin协程通过结构化并发机制,显著提升了Android异步编程的开发效率和代码质量。掌握以下要点能更好发挥其优势:合理选择CoroutineScope正确使用Dispatchers进行线程调度。

mnnde的博客 2851

Android协程简介 -- 基础概念

之前通过一个登录请求,简单了解Android协程的实现方式。相信很多人和我刚开始的时候一样,看的云里雾里的不清楚。这是因为我们对协程缺乏基础的了解。这篇文章,我们就详细介绍一下协程相关的基础知识。协程的概念协程优点协程相关的类、函数结构化并发如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

嘴巴吃糖了 1437

Android神兵利器之协程和Lifecycle

本文并没有讲什么比较深入的东西,主要还是从实际应用出发让我们对协程和Lifecycle有更多的理解,能更加灵活地使用它们提升代码质量和开发效率。在架构演进这一过程中最核心的问题还是解决实际问题,而不是为了演进而演进,以旧架构的思维来使用新架构新工具,否则终究还是屎山堆积。如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

Androiddddd的博客 1367

Android协程

在Looper的死循环中,它会不断地从消息队列中取出消息,并将消息分发给对应的Handler处理。当消息队列为空时,Looper会一直循环等待新的消息到达。在等待消息期间,Looper的死循环会阻塞主线程,因为它会一直占用主线程的执行时间片。这意味着主线程无法继续执行其他任务或响应用户的输入事件或系统事件。只有当主线程长时间占用了 CPU 或其他系统资源,并且长时间无法响应用户输入事件或完成关键操作时,才会触发 ANR 错误。耗时操作本身并不会导致主线程卡死,导致主线程卡死的真正原因是。

m0_61130325的博客 3914

Kotlin - 协程基础及原理,4年小Android的心路历程

协程上下文在协程中的作用非常大,有它在相当于协程有了装备卡槽一样。你可以将你想添加的上下文对象合并到参数上,然后在其他地方使用。的数据结构有如下特点:可以通过[]以类似List的方式访问任何一个协程上下文对象,[]内是目标协程上下文。协程上下文可以通过的方式依次累加,当然+=也是可用的。我们来自定义一个协程上下文给协程添加一个名字:应用到示例中:suspend {.name}”)})自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

2401_84149213的博客 1338

kotlin之协程基础知识

从本质上来说,协程是一种轻量级的线程,不同协程之间的切换仅在编程语言的层面就可以实现。而线程之间的切换需要依靠操作系统的调度才能实现。我们可以在单个线程中创建多个协程,协程支持挂起,挂起的同时又不会阻塞当前线程,这也是我们常说的非阻塞式挂起。

hexin5213578的博客 1562

android 协程基础(一)

android 协程基础基础概念协程挂起和恢复挂起和阻塞调度器Dispatchers.MainDispatchers.IODispatchers.Default结构化并发-CoroutineScope 背景:上家公司干了三年,开发语言主要用的JAVA和flutter来开发的,新的公司全是kotlin,所以又要把上上家公司用的kotlin要回顾下了,主要还是协程和Jetpack相关。 基础概念 协程 协程并不是一个新的概念,它并不是 Kotlin 发明的。它们已经存在了几十年,并且在 Go 等其他一些编程语言

HUandroid的博客 1507
上一篇: android 协程基础(一)
下一篇: android 媒体文件分区适配
HUandroid
博客等级 码龄10年 35粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值