【Kotlin】协程

打印 上一主题 下一主题

主题 847|帖子 847|积分 2541

1 前言

​    相较于 C# 中的协程(详见 → 【Unity3D】协同程序),Kotlin 中协程更机动,难度更大。
​    协程是一种并发设计模式,用于简化异步编程,它允许以顺序化的方式表达异步操纵,避免回调地狱等问题。使用协程,可以将异步操纵的代码像同步代码一样写,而无需显式地管理线程。
​    在 Kotlin 中,协程由 kotlinx.coroutines 库提供支持。它使用 suspend 修饰符来标挂念起函数(即可暂停执行并稍后恢复执行的函数),这使得编写异步代码更加直观和简单。
​    协程和线程具有以下异同点。
​    1)并发模型

  • 线程:线程是操纵体系提供的执行单元,一个进程可以拥有多个线程,线程之间相对独立,数据共享需要通过特殊本领(如锁)保证安全。
  • 协程:协程是一种用户态的轻量级线程,由开辟者控制其运行与暂停,可以在同一线程上并发执行,通过挂起和恢复的方式,实现非阻塞的并发。
​    2)资源消耗

  • 线程:每个线程都需要分配一定的内存和体系资源,线程切换时会有一定的开销。
  • 协程:协程是用户级的,由协程调度器(Coroutine Dispatcher)调度,通常会复用较少的体系资源,因此更轻量级。
​    3)编程模型

  • 线程:多线程编程通常以共享状态和锁为基础,编写并发代码较为复杂。
  • 协程:协程提供了一种结构化并发编程的方式,通过挂起函数的调用实当代码的暂停和恢复,使得异步编程更易于理解和维护。
​    4)错误处理处罚

  • 线程:多线程编程中,错误处理处罚相对困难,需要开辟者手动处理处罚异常和线程间的通信。
  • 协程:协程提供了更加简单和划一的错误处理处罚方式,通过结构化的异常处理处罚机制,可以轻松处理处罚协程中的异常。
​    5)性能

  • 线程:创建和管理线程大概会带来较大的开销,尤其是在大量线程同时运行时,线程切换的开销也会比较高。
  • 协程:协程由于是轻量级的用户级线程,资源消耗较少,因此在大规模并发场景下大概体现更优。
​    总的来说,协程相比于传统的线程模型,更加机动、轻量级,并且提供了更加简单和结构化的并发编程方式,使得异步编程更加容易和优雅。
2 协程相关类图


3 协程源码

3.1 协程作用域源码(CoroutinueScope)

​    协程的作用域定义了协程的作用域范围,当该作用域被销毁时,此中的协程也会被取消。协程的作用阈主要有 CoroutineScope、MainScope、GlobalScope、lifecycleScope 、viewModelScope,主要区别如下。

  • CoroutineScope:CoroutineScope 是通用的协程作用域,用于定义协程的作用域范围,当该作用域被销毁时,此中的协程也会被取消。
  • MainScope:MainScope 是 Kotlin 中提供的特定于 Android 的协程作用域,用于在 Android 主线程上启动协程,通常在 Android 的 Activity 或 Fragment 中使用 MainScope,以确保在主线程上运行协程,并在相关生命周期结束时取消协程。
  • GlobalScope:GlobalScope 是 Kotlin 中提供的一个全局协程作用域,它是一个顶层对象,用户可以在任何地方使用 GlobalScope 启动协程,但不保举在 Android 中使用它,由于它的生命周期很长,并且不受管理,大概导致内存走漏等问题。
  • lifecycleScope:lifecycleScope 是 Android Jetpack 中的 Lifecycle 模块提供的一个扩展属性,它的生命周期与相关的组件(如 Activity 或 Fragment)的生命周期绑定,从而避免内存走漏等问题。
  • viewModelScope:viewModelScope 是 Android Jetpack 中 Lifecycle 模块提供的一个扩展属性,它的生命周期与 ViewModel 的生命周期绑定,从而避免内存走漏等问题。
3.1.1 CoroutineScope
  1. public fun CoroutineScope(context: CoroutineContext): CoroutineScope =
  2.     ContextScope(if (context[Job] != null) context else context + Job())
复制代码
​    说明:CoroutineScope 是通用的协程作用域,用于定义协程的作用域范围,当该作用域被销毁时,此中的协程也会被取消。
3.1.2 MainScope
  1. public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)
复制代码
​    说明:MainScope 是 Kotlin 中提供的特定于 Android 的协程作用域,用于在 Android 主线程上启动协程,通常在 Android 的 Activity 或 Fragment 中使用 MainScope,以确保在主线程上运行协程,并在相关生命周期结束时取消协程。
3.1.3 GlobalScope
  1. public object GlobalScope : CoroutineScope
复制代码
​    说明:GlobalScope 是 Kotlin 中提供的一个全局协程作用域,它是一个顶层对象,用户可以在任何地方使用 GlobalScope 启动协程,但不保举在 Android 中使用它,由于它的生命周期很长,并且不受管理,大概导致内存走漏等问题。GlobalScope 是一个单例,其作用域的生命周期跟随应用程序的生命周期,中间不能取消(cancel)。
3.1.4 lifecycleScope
  1. public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
  2.     get() = lifecycle.coroutineScope
  3. // -----------------------------------------------------------
  4. public val Lifecycle.coroutineScope: LifecycleCoroutineScope
  5.     get() {
  6. <?xml version="1.0" encoding="utf-8"?>
  7. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  8.     xmlns:tools="http://schemas.android.com/tools"
  9.     android:layout_width="match_parent"
  10.     android:layout_height="match_parent"
  11.     tools:context=".MainActivity"
  12.     android:orientation="vertical"
  13.     android:gravity="center">
  14.    <ImageView
  15.        android:id="@+id/imageView"
  16.        android:layout_height="match_parent"
  17.        android:layout_width="match_parent"
  18.        android:scaleType="centerCrop"
  19.        android:visibility="gone" />
  20.    <Button
  21.        android:id="@+id/btn_back"
  22.        android:layout_width="250dp"
  23.        android:layout_height="wrap_content"
  24.        android:text="加载图片"
  25.        android:textSize="40sp"/>
  26. </LinearLayout>  while (true) {
  27. <?xml version="1.0" encoding="utf-8"?>
  28. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  29.     xmlns:tools="http://schemas.android.com/tools"
  30.     android:layout_width="match_parent"
  31.     android:layout_height="match_parent"
  32.     tools:context=".MainActivity"
  33.     android:orientation="vertical"
  34.     android:gravity="center">
  35.    <ImageView
  36.        android:id="@+id/imageView"
  37.        android:layout_height="match_parent"
  38.        android:layout_width="match_parent"
  39.        android:scaleType="centerCrop"
  40.        android:visibility="gone" />
  41.    <Button
  42.        android:id="@+id/btn_back"
  43.        android:layout_width="250dp"
  44.        android:layout_height="wrap_content"
  45.        android:text="加载图片"
  46.        android:textSize="40sp"/>
  47. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  48. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  49.     xmlns:tools="http://schemas.android.com/tools"
  50.     android:layout_width="match_parent"
  51.     android:layout_height="match_parent"
  52.     tools:context=".MainActivity"
  53.     android:orientation="vertical"
  54.     android:gravity="center">
  55.    <ImageView
  56.        android:id="@+id/imageView"
  57.        android:layout_height="match_parent"
  58.        android:layout_width="match_parent"
  59.        android:scaleType="centerCrop"
  60.        android:visibility="gone" />
  61.    <Button
  62.        android:id="@+id/btn_back"
  63.        android:layout_width="250dp"
  64.        android:layout_height="wrap_content"
  65.        android:text="加载图片"
  66.        android:textSize="40sp"/>
  67. </LinearLayout>val existing = mInternalScopeRef.get() as LifecycleCoroutineScopeImpl?
  68. <?xml version="1.0" encoding="utf-8"?>
  69. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  70.     xmlns:tools="http://schemas.android.com/tools"
  71.     android:layout_width="match_parent"
  72.     android:layout_height="match_parent"
  73.     tools:context=".MainActivity"
  74.     android:orientation="vertical"
  75.     android:gravity="center">
  76.    <ImageView
  77.        android:id="@+id/imageView"
  78.        android:layout_height="match_parent"
  79.        android:layout_width="match_parent"
  80.        android:scaleType="centerCrop"
  81.        android:visibility="gone" />
  82.    <Button
  83.        android:id="@+id/btn_back"
  84.        android:layout_width="250dp"
  85.        android:layout_height="wrap_content"
  86.        android:text="加载图片"
  87.        android:textSize="40sp"/>
  88. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  89. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  90.     xmlns:tools="http://schemas.android.com/tools"
  91.     android:layout_width="match_parent"
  92.     android:layout_height="match_parent"
  93.     tools:context=".MainActivity"
  94.     android:orientation="vertical"
  95.     android:gravity="center">
  96.    <ImageView
  97.        android:id="@+id/imageView"
  98.        android:layout_height="match_parent"
  99.        android:layout_width="match_parent"
  100.        android:scaleType="centerCrop"
  101.        android:visibility="gone" />
  102.    <Button
  103.        android:id="@+id/btn_back"
  104.        android:layout_width="250dp"
  105.        android:layout_height="wrap_content"
  106.        android:text="加载图片"
  107.        android:textSize="40sp"/>
  108. </LinearLayout>if (existing != null) {
  109. <?xml version="1.0" encoding="utf-8"?>
  110. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  111.     xmlns:tools="http://schemas.android.com/tools"
  112.     android:layout_width="match_parent"
  113.     android:layout_height="match_parent"
  114.     tools:context=".MainActivity"
  115.     android:orientation="vertical"
  116.     android:gravity="center">
  117.    <ImageView
  118.        android:id="@+id/imageView"
  119.        android:layout_height="match_parent"
  120.        android:layout_width="match_parent"
  121.        android:scaleType="centerCrop"
  122.        android:visibility="gone" />
  123.    <Button
  124.        android:id="@+id/btn_back"
  125.        android:layout_width="250dp"
  126.        android:layout_height="wrap_content"
  127.        android:text="加载图片"
  128.        android:textSize="40sp"/>
  129. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  130. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  131.     xmlns:tools="http://schemas.android.com/tools"
  132.     android:layout_width="match_parent"
  133.     android:layout_height="match_parent"
  134.     tools:context=".MainActivity"
  135.     android:orientation="vertical"
  136.     android:gravity="center">
  137.    <ImageView
  138.        android:id="@+id/imageView"
  139.        android:layout_height="match_parent"
  140.        android:layout_width="match_parent"
  141.        android:scaleType="centerCrop"
  142.        android:visibility="gone" />
  143.    <Button
  144.        android:id="@+id/btn_back"
  145.        android:layout_width="250dp"
  146.        android:layout_height="wrap_content"
  147.        android:text="加载图片"
  148.        android:textSize="40sp"/>
  149. </LinearLayout>    return existing
  150. <?xml version="1.0" encoding="utf-8"?>
  151. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  152.     xmlns:tools="http://schemas.android.com/tools"
  153.     android:layout_width="match_parent"
  154.     android:layout_height="match_parent"
  155.     tools:context=".MainActivity"
  156.     android:orientation="vertical"
  157.     android:gravity="center">
  158.    <ImageView
  159.        android:id="@+id/imageView"
  160.        android:layout_height="match_parent"
  161.        android:layout_width="match_parent"
  162.        android:scaleType="centerCrop"
  163.        android:visibility="gone" />
  164.    <Button
  165.        android:id="@+id/btn_back"
  166.        android:layout_width="250dp"
  167.        android:layout_height="wrap_content"
  168.        android:text="加载图片"
  169.        android:textSize="40sp"/>
  170. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  171. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  172.     xmlns:tools="http://schemas.android.com/tools"
  173.     android:layout_width="match_parent"
  174.     android:layout_height="match_parent"
  175.     tools:context=".MainActivity"
  176.     android:orientation="vertical"
  177.     android:gravity="center">
  178.    <ImageView
  179.        android:id="@+id/imageView"
  180.        android:layout_height="match_parent"
  181.        android:layout_width="match_parent"
  182.        android:scaleType="centerCrop"
  183.        android:visibility="gone" />
  184.    <Button
  185.        android:id="@+id/btn_back"
  186.        android:layout_width="250dp"
  187.        android:layout_height="wrap_content"
  188.        android:text="加载图片"
  189.        android:textSize="40sp"/>
  190. </LinearLayout>}
  191. <?xml version="1.0" encoding="utf-8"?>
  192. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  193.     xmlns:tools="http://schemas.android.com/tools"
  194.     android:layout_width="match_parent"
  195.     android:layout_height="match_parent"
  196.     tools:context=".MainActivity"
  197.     android:orientation="vertical"
  198.     android:gravity="center">
  199.    <ImageView
  200.        android:id="@+id/imageView"
  201.        android:layout_height="match_parent"
  202.        android:layout_width="match_parent"
  203.        android:scaleType="centerCrop"
  204.        android:visibility="gone" />
  205.    <Button
  206.        android:id="@+id/btn_back"
  207.        android:layout_width="250dp"
  208.        android:layout_height="wrap_content"
  209.        android:text="加载图片"
  210.        android:textSize="40sp"/>
  211. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  212. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  213.     xmlns:tools="http://schemas.android.com/tools"
  214.     android:layout_width="match_parent"
  215.     android:layout_height="match_parent"
  216.     tools:context=".MainActivity"
  217.     android:orientation="vertical"
  218.     android:gravity="center">
  219.    <ImageView
  220.        android:id="@+id/imageView"
  221.        android:layout_height="match_parent"
  222.        android:layout_width="match_parent"
  223.        android:scaleType="centerCrop"
  224.        android:visibility="gone" />
  225.    <Button
  226.        android:id="@+id/btn_back"
  227.        android:layout_width="250dp"
  228.        android:layout_height="wrap_content"
  229.        android:text="加载图片"
  230.        android:textSize="40sp"/>
  231. </LinearLayout>val newScope = LifecycleCoroutineScopeImpl(this,
  232. <?xml version="1.0" encoding="utf-8"?>
  233. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  234.     xmlns:tools="http://schemas.android.com/tools"
  235.     android:layout_width="match_parent"
  236.     android:layout_height="match_parent"
  237.     tools:context=".MainActivity"
  238.     android:orientation="vertical"
  239.     android:gravity="center">
  240.    <ImageView
  241.        android:id="@+id/imageView"
  242.        android:layout_height="match_parent"
  243.        android:layout_width="match_parent"
  244.        android:scaleType="centerCrop"
  245.        android:visibility="gone" />
  246.    <Button
  247.        android:id="@+id/btn_back"
  248.        android:layout_width="250dp"
  249.        android:layout_height="wrap_content"
  250.        android:text="加载图片"
  251.        android:textSize="40sp"/>
  252. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  253. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  254.     xmlns:tools="http://schemas.android.com/tools"
  255.     android:layout_width="match_parent"
  256.     android:layout_height="match_parent"
  257.     tools:context=".MainActivity"
  258.     android:orientation="vertical"
  259.     android:gravity="center">
  260.    <ImageView
  261.        android:id="@+id/imageView"
  262.        android:layout_height="match_parent"
  263.        android:layout_width="match_parent"
  264.        android:scaleType="centerCrop"
  265.        android:visibility="gone" />
  266.    <Button
  267.        android:id="@+id/btn_back"
  268.        android:layout_width="250dp"
  269.        android:layout_height="wrap_content"
  270.        android:text="加载图片"
  271.        android:textSize="40sp"/>
  272. </LinearLayout>    SupervisorJob() + Dispatchers.Main.immediate
  273. <?xml version="1.0" encoding="utf-8"?>
  274. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  275.     xmlns:tools="http://schemas.android.com/tools"
  276.     android:layout_width="match_parent"
  277.     android:layout_height="match_parent"
  278.     tools:context=".MainActivity"
  279.     android:orientation="vertical"
  280.     android:gravity="center">
  281.    <ImageView
  282.        android:id="@+id/imageView"
  283.        android:layout_height="match_parent"
  284.        android:layout_width="match_parent"
  285.        android:scaleType="centerCrop"
  286.        android:visibility="gone" />
  287.    <Button
  288.        android:id="@+id/btn_back"
  289.        android:layout_width="250dp"
  290.        android:layout_height="wrap_content"
  291.        android:text="加载图片"
  292.        android:textSize="40sp"/>
  293. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  294. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  295.     xmlns:tools="http://schemas.android.com/tools"
  296.     android:layout_width="match_parent"
  297.     android:layout_height="match_parent"
  298.     tools:context=".MainActivity"
  299.     android:orientation="vertical"
  300.     android:gravity="center">
  301.    <ImageView
  302.        android:id="@+id/imageView"
  303.        android:layout_height="match_parent"
  304.        android:layout_width="match_parent"
  305.        android:scaleType="centerCrop"
  306.        android:visibility="gone" />
  307.    <Button
  308.        android:id="@+id/btn_back"
  309.        android:layout_width="250dp"
  310.        android:layout_height="wrap_content"
  311.        android:text="加载图片"
  312.        android:textSize="40sp"/>
  313. </LinearLayout>)
  314. <?xml version="1.0" encoding="utf-8"?>
  315. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  316.     xmlns:tools="http://schemas.android.com/tools"
  317.     android:layout_width="match_parent"
  318.     android:layout_height="match_parent"
  319.     tools:context=".MainActivity"
  320.     android:orientation="vertical"
  321.     android:gravity="center">
  322.    <ImageView
  323.        android:id="@+id/imageView"
  324.        android:layout_height="match_parent"
  325.        android:layout_width="match_parent"
  326.        android:scaleType="centerCrop"
  327.        android:visibility="gone" />
  328.    <Button
  329.        android:id="@+id/btn_back"
  330.        android:layout_width="250dp"
  331.        android:layout_height="wrap_content"
  332.        android:text="加载图片"
  333.        android:textSize="40sp"/>
  334. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  335. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  336.     xmlns:tools="http://schemas.android.com/tools"
  337.     android:layout_width="match_parent"
  338.     android:layout_height="match_parent"
  339.     tools:context=".MainActivity"
  340.     android:orientation="vertical"
  341.     android:gravity="center">
  342.    <ImageView
  343.        android:id="@+id/imageView"
  344.        android:layout_height="match_parent"
  345.        android:layout_width="match_parent"
  346.        android:scaleType="centerCrop"
  347.        android:visibility="gone" />
  348.    <Button
  349.        android:id="@+id/btn_back"
  350.        android:layout_width="250dp"
  351.        android:layout_height="wrap_content"
  352.        android:text="加载图片"
  353.        android:textSize="40sp"/>
  354. </LinearLayout>if (mInternalScopeRef.compareAndSet(null, newScope)) {
  355. <?xml version="1.0" encoding="utf-8"?>
  356. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  357.     xmlns:tools="http://schemas.android.com/tools"
  358.     android:layout_width="match_parent"
  359.     android:layout_height="match_parent"
  360.     tools:context=".MainActivity"
  361.     android:orientation="vertical"
  362.     android:gravity="center">
  363.    <ImageView
  364.        android:id="@+id/imageView"
  365.        android:layout_height="match_parent"
  366.        android:layout_width="match_parent"
  367.        android:scaleType="centerCrop"
  368.        android:visibility="gone" />
  369.    <Button
  370.        android:id="@+id/btn_back"
  371.        android:layout_width="250dp"
  372.        android:layout_height="wrap_content"
  373.        android:text="加载图片"
  374.        android:textSize="40sp"/>
  375. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  376. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  377.     xmlns:tools="http://schemas.android.com/tools"
  378.     android:layout_width="match_parent"
  379.     android:layout_height="match_parent"
  380.     tools:context=".MainActivity"
  381.     android:orientation="vertical"
  382.     android:gravity="center">
  383.    <ImageView
  384.        android:id="@+id/imageView"
  385.        android:layout_height="match_parent"
  386.        android:layout_width="match_parent"
  387.        android:scaleType="centerCrop"
  388.        android:visibility="gone" />
  389.    <Button
  390.        android:id="@+id/btn_back"
  391.        android:layout_width="250dp"
  392.        android:layout_height="wrap_content"
  393.        android:text="加载图片"
  394.        android:textSize="40sp"/>
  395. </LinearLayout>    newScope.register()
  396. <?xml version="1.0" encoding="utf-8"?>
  397. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  398.     xmlns:tools="http://schemas.android.com/tools"
  399.     android:layout_width="match_parent"
  400.     android:layout_height="match_parent"
  401.     tools:context=".MainActivity"
  402.     android:orientation="vertical"
  403.     android:gravity="center">
  404.    <ImageView
  405.        android:id="@+id/imageView"
  406.        android:layout_height="match_parent"
  407.        android:layout_width="match_parent"
  408.        android:scaleType="centerCrop"
  409.        android:visibility="gone" />
  410.    <Button
  411.        android:id="@+id/btn_back"
  412.        android:layout_width="250dp"
  413.        android:layout_height="wrap_content"
  414.        android:text="加载图片"
  415.        android:textSize="40sp"/>
  416. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  417. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  418.     xmlns:tools="http://schemas.android.com/tools"
  419.     android:layout_width="match_parent"
  420.     android:layout_height="match_parent"
  421.     tools:context=".MainActivity"
  422.     android:orientation="vertical"
  423.     android:gravity="center">
  424.    <ImageView
  425.        android:id="@+id/imageView"
  426.        android:layout_height="match_parent"
  427.        android:layout_width="match_parent"
  428.        android:scaleType="centerCrop"
  429.        android:visibility="gone" />
  430.    <Button
  431.        android:id="@+id/btn_back"
  432.        android:layout_width="250dp"
  433.        android:layout_height="wrap_content"
  434.        android:text="加载图片"
  435.        android:textSize="40sp"/>
  436. </LinearLayout>    return newScope
  437. <?xml version="1.0" encoding="utf-8"?>
  438. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  439.     xmlns:tools="http://schemas.android.com/tools"
  440.     android:layout_width="match_parent"
  441.     android:layout_height="match_parent"
  442.     tools:context=".MainActivity"
  443.     android:orientation="vertical"
  444.     android:gravity="center">
  445.    <ImageView
  446.        android:id="@+id/imageView"
  447.        android:layout_height="match_parent"
  448.        android:layout_width="match_parent"
  449.        android:scaleType="centerCrop"
  450.        android:visibility="gone" />
  451.    <Button
  452.        android:id="@+id/btn_back"
  453.        android:layout_width="250dp"
  454.        android:layout_height="wrap_content"
  455.        android:text="加载图片"
  456.        android:textSize="40sp"/>
  457. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  458. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  459.     xmlns:tools="http://schemas.android.com/tools"
  460.     android:layout_width="match_parent"
  461.     android:layout_height="match_parent"
  462.     tools:context=".MainActivity"
  463.     android:orientation="vertical"
  464.     android:gravity="center">
  465.    <ImageView
  466.        android:id="@+id/imageView"
  467.        android:layout_height="match_parent"
  468.        android:layout_width="match_parent"
  469.        android:scaleType="centerCrop"
  470.        android:visibility="gone" />
  471.    <Button
  472.        android:id="@+id/btn_back"
  473.        android:layout_width="250dp"
  474.        android:layout_height="wrap_content"
  475.        android:text="加载图片"
  476.        android:textSize="40sp"/>
  477. </LinearLayout>}
  478. <?xml version="1.0" encoding="utf-8"?>
  479. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  480.     xmlns:tools="http://schemas.android.com/tools"
  481.     android:layout_width="match_parent"
  482.     android:layout_height="match_parent"
  483.     tools:context=".MainActivity"
  484.     android:orientation="vertical"
  485.     android:gravity="center">
  486.    <ImageView
  487.        android:id="@+id/imageView"
  488.        android:layout_height="match_parent"
  489.        android:layout_width="match_parent"
  490.        android:scaleType="centerCrop"
  491.        android:visibility="gone" />
  492.    <Button
  493.        android:id="@+id/btn_back"
  494.        android:layout_width="250dp"
  495.        android:layout_height="wrap_content"
  496.        android:text="加载图片"
  497.        android:textSize="40sp"/>
  498. </LinearLayout>  }
  499.     }
  500. // -----------------------------------------------------------
  501. internal class LifecycleCoroutineScopeImpl(
  502.     override val lifecycle: Lifecycle,
  503.     override val coroutineContext: CoroutineContext
  504. ) : LifecycleCoroutineScope(), LifecycleEventObserver
  505. // -----------------------------------------------------------
  506. public abstract class LifecycleCoroutineScope internal constructor() : CoroutineScope
复制代码
​    说明:lifecycleScope 是 Android Jetpack 中的 Lifecycle 模块提供的一个扩展属性,它的生命周期与相关的组件(如 Activity 或 Fragment)的生命周期绑定,从而避免内存走漏等问题。
​    使用 lifecycleScope 时,需要在 build.gradle 中引入以下依赖。
  1. implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
复制代码
​    并导入包名。
  1. import androidx.lifecycle.lifecycleScope
复制代码
​    AppCompatActivity、FragmentActivity 与 LifecycleOwner 存在以下继承关系。因此可以在 AppCompatActivity 和 FragmentActivity 中直接访问 lifecycleScope。
  1. AppCompatActivity → FragmentActivity → ComponentActivity → LifecycleOwner
复制代码
3.1.5 viewModelScope
  1. public val ViewModel.viewModelScope: CoroutineScope
  2.     get() {
  3. <?xml version="1.0" encoding="utf-8"?>
  4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5.     xmlns:tools="http://schemas.android.com/tools"
  6.     android:layout_width="match_parent"
  7.     android:layout_height="match_parent"
  8.     tools:context=".MainActivity"
  9.     android:orientation="vertical"
  10.     android:gravity="center">
  11.    <ImageView
  12.        android:id="@+id/imageView"
  13.        android:layout_height="match_parent"
  14.        android:layout_width="match_parent"
  15.        android:scaleType="centerCrop"
  16.        android:visibility="gone" />
  17.    <Button
  18.        android:id="@+id/btn_back"
  19.        android:layout_width="250dp"
  20.        android:layout_height="wrap_content"
  21.        android:text="加载图片"
  22.        android:textSize="40sp"/>
  23. </LinearLayout>  val scope: CoroutineScope? = this.getTag(JOB_KEY)
  24. <?xml version="1.0" encoding="utf-8"?>
  25. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  26.     xmlns:tools="http://schemas.android.com/tools"
  27.     android:layout_width="match_parent"
  28.     android:layout_height="match_parent"
  29.     tools:context=".MainActivity"
  30.     android:orientation="vertical"
  31.     android:gravity="center">
  32.    <ImageView
  33.        android:id="@+id/imageView"
  34.        android:layout_height="match_parent"
  35.        android:layout_width="match_parent"
  36.        android:scaleType="centerCrop"
  37.        android:visibility="gone" />
  38.    <Button
  39.        android:id="@+id/btn_back"
  40.        android:layout_width="250dp"
  41.        android:layout_height="wrap_content"
  42.        android:text="加载图片"
  43.        android:textSize="40sp"/>
  44. </LinearLayout>  if (scope != null) {
  45. <?xml version="1.0" encoding="utf-8"?>
  46. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  47.     xmlns:tools="http://schemas.android.com/tools"
  48.     android:layout_width="match_parent"
  49.     android:layout_height="match_parent"
  50.     tools:context=".MainActivity"
  51.     android:orientation="vertical"
  52.     android:gravity="center">
  53.    <ImageView
  54.        android:id="@+id/imageView"
  55.        android:layout_height="match_parent"
  56.        android:layout_width="match_parent"
  57.        android:scaleType="centerCrop"
  58.        android:visibility="gone" />
  59.    <Button
  60.        android:id="@+id/btn_back"
  61.        android:layout_width="250dp"
  62.        android:layout_height="wrap_content"
  63.        android:text="加载图片"
  64.        android:textSize="40sp"/>
  65. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  66. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  67.     xmlns:tools="http://schemas.android.com/tools"
  68.     android:layout_width="match_parent"
  69.     android:layout_height="match_parent"
  70.     tools:context=".MainActivity"
  71.     android:orientation="vertical"
  72.     android:gravity="center">
  73.    <ImageView
  74.        android:id="@+id/imageView"
  75.        android:layout_height="match_parent"
  76.        android:layout_width="match_parent"
  77.        android:scaleType="centerCrop"
  78.        android:visibility="gone" />
  79.    <Button
  80.        android:id="@+id/btn_back"
  81.        android:layout_width="250dp"
  82.        android:layout_height="wrap_content"
  83.        android:text="加载图片"
  84.        android:textSize="40sp"/>
  85. </LinearLayout>return scope
  86. <?xml version="1.0" encoding="utf-8"?>
  87. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  88.     xmlns:tools="http://schemas.android.com/tools"
  89.     android:layout_width="match_parent"
  90.     android:layout_height="match_parent"
  91.     tools:context=".MainActivity"
  92.     android:orientation="vertical"
  93.     android:gravity="center">
  94.    <ImageView
  95.        android:id="@+id/imageView"
  96.        android:layout_height="match_parent"
  97.        android:layout_width="match_parent"
  98.        android:scaleType="centerCrop"
  99.        android:visibility="gone" />
  100.    <Button
  101.        android:id="@+id/btn_back"
  102.        android:layout_width="250dp"
  103.        android:layout_height="wrap_content"
  104.        android:text="加载图片"
  105.        android:textSize="40sp"/>
  106. </LinearLayout>  }
  107. <?xml version="1.0" encoding="utf-8"?>
  108. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  109.     xmlns:tools="http://schemas.android.com/tools"
  110.     android:layout_width="match_parent"
  111.     android:layout_height="match_parent"
  112.     tools:context=".MainActivity"
  113.     android:orientation="vertical"
  114.     android:gravity="center">
  115.    <ImageView
  116.        android:id="@+id/imageView"
  117.        android:layout_height="match_parent"
  118.        android:layout_width="match_parent"
  119.        android:scaleType="centerCrop"
  120.        android:visibility="gone" />
  121.    <Button
  122.        android:id="@+id/btn_back"
  123.        android:layout_width="250dp"
  124.        android:layout_height="wrap_content"
  125.        android:text="加载图片"
  126.        android:textSize="40sp"/>
  127. </LinearLayout>  return setTagIfAbsent(JOB_KEY,
  128. <?xml version="1.0" encoding="utf-8"?>
  129. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  130.     xmlns:tools="http://schemas.android.com/tools"
  131.     android:layout_width="match_parent"
  132.     android:layout_height="match_parent"
  133.     tools:context=".MainActivity"
  134.     android:orientation="vertical"
  135.     android:gravity="center">
  136.    <ImageView
  137.        android:id="@+id/imageView"
  138.        android:layout_height="match_parent"
  139.        android:layout_width="match_parent"
  140.        android:scaleType="centerCrop"
  141.        android:visibility="gone" />
  142.    <Button
  143.        android:id="@+id/btn_back"
  144.        android:layout_width="250dp"
  145.        android:layout_height="wrap_content"
  146.        android:text="加载图片"
  147.        android:textSize="40sp"/>
  148. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  149. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  150.     xmlns:tools="http://schemas.android.com/tools"
  151.     android:layout_width="match_parent"
  152.     android:layout_height="match_parent"
  153.     tools:context=".MainActivity"
  154.     android:orientation="vertical"
  155.     android:gravity="center">
  156.    <ImageView
  157.        android:id="@+id/imageView"
  158.        android:layout_height="match_parent"
  159.        android:layout_width="match_parent"
  160.        android:scaleType="centerCrop"
  161.        android:visibility="gone" />
  162.    <Button
  163.        android:id="@+id/btn_back"
  164.        android:layout_width="250dp"
  165.        android:layout_height="wrap_content"
  166.        android:text="加载图片"
  167.        android:textSize="40sp"/>
  168. </LinearLayout>CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
  169. <?xml version="1.0" encoding="utf-8"?>
  170. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  171.     xmlns:tools="http://schemas.android.com/tools"
  172.     android:layout_width="match_parent"
  173.     android:layout_height="match_parent"
  174.     tools:context=".MainActivity"
  175.     android:orientation="vertical"
  176.     android:gravity="center">
  177.    <ImageView
  178.        android:id="@+id/imageView"
  179.        android:layout_height="match_parent"
  180.        android:layout_width="match_parent"
  181.        android:scaleType="centerCrop"
  182.        android:visibility="gone" />
  183.    <Button
  184.        android:id="@+id/btn_back"
  185.        android:layout_width="250dp"
  186.        android:layout_height="wrap_content"
  187.        android:text="加载图片"
  188.        android:textSize="40sp"/>
  189. </LinearLayout>  )
  190.     }
  191. // --------------------------------------------------------------------------
  192. internal class CloseableCoroutineScope(context: CoroutineContext) : Closeable, CoroutineScope {
  193.     override val coroutineContext: CoroutineContext = context
  194.     override fun close() {
  195. <?xml version="1.0" encoding="utf-8"?>
  196. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  197.     xmlns:tools="http://schemas.android.com/tools"
  198.     android:layout_width="match_parent"
  199.     android:layout_height="match_parent"
  200.     tools:context=".MainActivity"
  201.     android:orientation="vertical"
  202.     android:gravity="center">
  203.    <ImageView
  204.        android:id="@+id/imageView"
  205.        android:layout_height="match_parent"
  206.        android:layout_width="match_parent"
  207.        android:scaleType="centerCrop"
  208.        android:visibility="gone" />
  209.    <Button
  210.        android:id="@+id/btn_back"
  211.        android:layout_width="250dp"
  212.        android:layout_height="wrap_content"
  213.        android:text="加载图片"
  214.        android:textSize="40sp"/>
  215. </LinearLayout>  coroutineContext.cancel()
  216.     }
  217. }
复制代码
​    说明:viewModelScope 是 Android Jetpack 中 Lifecycle 模块提供的一个扩展属性,它的生命周期与 ViewModel 的生命周期绑定,从而避免内存走漏等问题。
​    使用 viewModelScope 时,需要在 build.gradle 中引入以下依赖。
  1. implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
复制代码
​    并导入包名。
  1. import androidx.lifecycle.viewModelScope
复制代码
3.2 协程调度器源码(Dispatchers)
  1. public actual object Dispatchers {
  2.     // 线程池, 适合执行CPU密集型任务(大量占用量CPU的任务)
  3.     public actual val Default: CoroutineDispatcher = DefaultScheduler
  4.     // Android中是UI线程, Swing中是invokerLater线程
  5.     public actual val Main: MainCoroutineDispatcher get() = MainDispatcherLoader.dispatcher
  6.     // 在当前线程上执行
  7.     public actual val Unconfined: CoroutineDispatcher = kotlinx.coroutines.Unconfined
  8.     // 线程池, 适合执行磁盘读写、网络IO、数据库操作等任务
  9.     public val IO: CoroutineDispatcher = DefaultIoScheduler
  10.     // ...
  11. }
复制代码
3.3 协程启动方式源码

​    协程的启动方式主要有 launch、async、runBlocking、withContext,它们的区别如下。

  • launch:launch 用于启动一个新的协程,并返回一个 Job 对象,该对象代表了这个新协程;启动的协程在背景运行,不会阻塞当前线程的执行,并且不会返回协程的执行结果。
  • async:async 用于启动一个新的协程,并返回一个 Deferred 对象,它是 Job 的子类,可以通过 await 函数获取协程的执行结果;启动的协程在背景运行,不会阻塞当前线程的执行。
  • runBlocking:runBlocking 是一个顶层函数,用于启动一个新的协程并阻塞当前线程,直到协程执行完成; runBlocking 本质上是为了在顶层(如 main 函数)使用协程,以及在测试中使用协程;在生产代码中不保举使用 runBlocking,由于它会阻塞当前线程,大概导致性能问题。
  • withContext:withContext 用于切换协程的上下文,它会创建一个新的协程并在指定的上下文中执行,它会挂起原来的协程,待新协程执行结束后才恢复执行。
3.3.1 launch
  1. public fun CoroutineScope.launch(
  2.     context: CoroutineContext = EmptyCoroutineContext,
  3.     start: CoroutineStart = CoroutineStart.DEFAULT,
  4.     block: suspend CoroutineScope.() -> Unit
  5. ): Job {
  6.     val newContext = newCoroutineContext(context)
  7.     val coroutine = if (start.isLazy)
  8. <?xml version="1.0" encoding="utf-8"?>
  9. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  10.     xmlns:tools="http://schemas.android.com/tools"
  11.     android:layout_width="match_parent"
  12.     android:layout_height="match_parent"
  13.     tools:context=".MainActivity"
  14.     android:orientation="vertical"
  15.     android:gravity="center">
  16.    <ImageView
  17.        android:id="@+id/imageView"
  18.        android:layout_height="match_parent"
  19.        android:layout_width="match_parent"
  20.        android:scaleType="centerCrop"
  21.        android:visibility="gone" />
  22.    <Button
  23.        android:id="@+id/btn_back"
  24.        android:layout_width="250dp"
  25.        android:layout_height="wrap_content"
  26.        android:text="加载图片"
  27.        android:textSize="40sp"/>
  28. </LinearLayout>  LazyStandaloneCoroutine(newContext, block) else
  29. <?xml version="1.0" encoding="utf-8"?>
  30. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  31.     xmlns:tools="http://schemas.android.com/tools"
  32.     android:layout_width="match_parent"
  33.     android:layout_height="match_parent"
  34.     tools:context=".MainActivity"
  35.     android:orientation="vertical"
  36.     android:gravity="center">
  37.    <ImageView
  38.        android:id="@+id/imageView"
  39.        android:layout_height="match_parent"
  40.        android:layout_width="match_parent"
  41.        android:scaleType="centerCrop"
  42.        android:visibility="gone" />
  43.    <Button
  44.        android:id="@+id/btn_back"
  45.        android:layout_width="250dp"
  46.        android:layout_height="wrap_content"
  47.        android:text="加载图片"
  48.        android:textSize="40sp"/>
  49. </LinearLayout>  StandaloneCoroutine(newContext, active = true)
  50.     coroutine.start(start, coroutine, block)
  51.     return coroutine
  52. }
复制代码
​    说明:launch 用于启动一个新的协程,并返回一个 Job 对象,该对象代表了这个新协程;启动的协程在背景运行,不会阻塞当前线程的执行,并且不会返回协程的执行结果。
3.3.2 async
  1. public fun <T> CoroutineScope.async(
  2.     context: CoroutineContext = EmptyCoroutineContext,
  3.     start: CoroutineStart = CoroutineStart.DEFAULT,
  4.     block: suspend CoroutineScope.() -> T
  5. ): Deferred<T> {
  6.     val newContext = newCoroutineContext(context)
  7.     val coroutine = if (start.isLazy)
  8. <?xml version="1.0" encoding="utf-8"?>
  9. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  10.     xmlns:tools="http://schemas.android.com/tools"
  11.     android:layout_width="match_parent"
  12.     android:layout_height="match_parent"
  13.     tools:context=".MainActivity"
  14.     android:orientation="vertical"
  15.     android:gravity="center">
  16.    <ImageView
  17.        android:id="@+id/imageView"
  18.        android:layout_height="match_parent"
  19.        android:layout_width="match_parent"
  20.        android:scaleType="centerCrop"
  21.        android:visibility="gone" />
  22.    <Button
  23.        android:id="@+id/btn_back"
  24.        android:layout_width="250dp"
  25.        android:layout_height="wrap_content"
  26.        android:text="加载图片"
  27.        android:textSize="40sp"/>
  28. </LinearLayout>  LazyDeferredCoroutine(newContext, block) else
  29. <?xml version="1.0" encoding="utf-8"?>
  30. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  31.     xmlns:tools="http://schemas.android.com/tools"
  32.     android:layout_width="match_parent"
  33.     android:layout_height="match_parent"
  34.     tools:context=".MainActivity"
  35.     android:orientation="vertical"
  36.     android:gravity="center">
  37.    <ImageView
  38.        android:id="@+id/imageView"
  39.        android:layout_height="match_parent"
  40.        android:layout_width="match_parent"
  41.        android:scaleType="centerCrop"
  42.        android:visibility="gone" />
  43.    <Button
  44.        android:id="@+id/btn_back"
  45.        android:layout_width="250dp"
  46.        android:layout_height="wrap_content"
  47.        android:text="加载图片"
  48.        android:textSize="40sp"/>
  49. </LinearLayout>  DeferredCoroutine<T>(newContext, active = true)
  50.     coroutine.start(start, coroutine, block)
  51.     return coroutine
  52. }
复制代码
​    说明:async 用于启动一个新的协程,并返回一个 Deferred 对象,它是 Job 的子类,可以通过 await 函数获取协程的执行结果;启动的协程在背景运行,不会阻塞当前线程的执行。
3.3.3 runBlocking

​    runBlocking 官方介绍见 → runBlocking
  1. public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {
  2.     ...
  3.     val currentThread = Thread.currentThread()
  4.     val contextInterceptor = context[ContinuationInterceptor]
  5.     val eventLoop: EventLoop?
  6.     val newContext: CoroutineContext
  7.     if (contextInterceptor == null) {
  8. <?xml version="1.0" encoding="utf-8"?>
  9. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  10.     xmlns:tools="http://schemas.android.com/tools"
  11.     android:layout_width="match_parent"
  12.     android:layout_height="match_parent"
  13.     tools:context=".MainActivity"
  14.     android:orientation="vertical"
  15.     android:gravity="center">
  16.    <ImageView
  17.        android:id="@+id/imageView"
  18.        android:layout_height="match_parent"
  19.        android:layout_width="match_parent"
  20.        android:scaleType="centerCrop"
  21.        android:visibility="gone" />
  22.    <Button
  23.        android:id="@+id/btn_back"
  24.        android:layout_width="250dp"
  25.        android:layout_height="wrap_content"
  26.        android:text="加载图片"
  27.        android:textSize="40sp"/>
  28. </LinearLayout>  // 如果没有指定调度器(dispatcher), 则创建或使用私有事件循环(eventLoop)
  29. <?xml version="1.0" encoding="utf-8"?>
  30. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  31.     xmlns:tools="http://schemas.android.com/tools"
  32.     android:layout_width="match_parent"
  33.     android:layout_height="match_parent"
  34.     tools:context=".MainActivity"
  35.     android:orientation="vertical"
  36.     android:gravity="center">
  37.    <ImageView
  38.        android:id="@+id/imageView"
  39.        android:layout_height="match_parent"
  40.        android:layout_width="match_parent"
  41.        android:scaleType="centerCrop"
  42.        android:visibility="gone" />
  43.    <Button
  44.        android:id="@+id/btn_back"
  45.        android:layout_width="250dp"
  46.        android:layout_height="wrap_content"
  47.        android:text="加载图片"
  48.        android:textSize="40sp"/>
  49. </LinearLayout>  eventLoop = ThreadLocalEventLoop.eventLoop
  50. <?xml version="1.0" encoding="utf-8"?>
  51. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  52.     xmlns:tools="http://schemas.android.com/tools"
  53.     android:layout_width="match_parent"
  54.     android:layout_height="match_parent"
  55.     tools:context=".MainActivity"
  56.     android:orientation="vertical"
  57.     android:gravity="center">
  58.    <ImageView
  59.        android:id="@+id/imageView"
  60.        android:layout_height="match_parent"
  61.        android:layout_width="match_parent"
  62.        android:scaleType="centerCrop"
  63.        android:visibility="gone" />
  64.    <Button
  65.        android:id="@+id/btn_back"
  66.        android:layout_width="250dp"
  67.        android:layout_height="wrap_content"
  68.        android:text="加载图片"
  69.        android:textSize="40sp"/>
  70. </LinearLayout>  newContext = GlobalScope.newCoroutineContext(context + eventLoop)
  71.     } else {
  72. <?xml version="1.0" encoding="utf-8"?>
  73. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  74.     xmlns:tools="http://schemas.android.com/tools"
  75.     android:layout_width="match_parent"
  76.     android:layout_height="match_parent"
  77.     tools:context=".MainActivity"
  78.     android:orientation="vertical"
  79.     android:gravity="center">
  80.    <ImageView
  81.        android:id="@+id/imageView"
  82.        android:layout_height="match_parent"
  83.        android:layout_width="match_parent"
  84.        android:scaleType="centerCrop"
  85.        android:visibility="gone" />
  86.    <Button
  87.        android:id="@+id/btn_back"
  88.        android:layout_width="250dp"
  89.        android:layout_height="wrap_content"
  90.        android:text="加载图片"
  91.        android:textSize="40sp"/>
  92. </LinearLayout>  eventLoop = (contextInterceptor as? EventLoop)?.takeIf { it.shouldBeProcessedFromContext() }
  93. <?xml version="1.0" encoding="utf-8"?>
  94. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  95.     xmlns:tools="http://schemas.android.com/tools"
  96.     android:layout_width="match_parent"
  97.     android:layout_height="match_parent"
  98.     tools:context=".MainActivity"
  99.     android:orientation="vertical"
  100.     android:gravity="center">
  101.    <ImageView
  102.        android:id="@+id/imageView"
  103.        android:layout_height="match_parent"
  104.        android:layout_width="match_parent"
  105.        android:scaleType="centerCrop"
  106.        android:visibility="gone" />
  107.    <Button
  108.        android:id="@+id/btn_back"
  109.        android:layout_width="250dp"
  110.        android:layout_height="wrap_content"
  111.        android:text="加载图片"
  112.        android:textSize="40sp"/>
  113. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  114. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  115.     xmlns:tools="http://schemas.android.com/tools"
  116.     android:layout_width="match_parent"
  117.     android:layout_height="match_parent"
  118.     tools:context=".MainActivity"
  119.     android:orientation="vertical"
  120.     android:gravity="center">
  121.    <ImageView
  122.        android:id="@+id/imageView"
  123.        android:layout_height="match_parent"
  124.        android:layout_width="match_parent"
  125.        android:scaleType="centerCrop"
  126.        android:visibility="gone" />
  127.    <Button
  128.        android:id="@+id/btn_back"
  129.        android:layout_width="250dp"
  130.        android:layout_height="wrap_content"
  131.        android:text="加载图片"
  132.        android:textSize="40sp"/>
  133. </LinearLayout>?: ThreadLocalEventLoop.currentOrNull()
  134. <?xml version="1.0" encoding="utf-8"?>
  135. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  136.     xmlns:tools="http://schemas.android.com/tools"
  137.     android:layout_width="match_parent"
  138.     android:layout_height="match_parent"
  139.     tools:context=".MainActivity"
  140.     android:orientation="vertical"
  141.     android:gravity="center">
  142.    <ImageView
  143.        android:id="@+id/imageView"
  144.        android:layout_height="match_parent"
  145.        android:layout_width="match_parent"
  146.        android:scaleType="centerCrop"
  147.        android:visibility="gone" />
  148.    <Button
  149.        android:id="@+id/btn_back"
  150.        android:layout_width="250dp"
  151.        android:layout_height="wrap_content"
  152.        android:text="加载图片"
  153.        android:textSize="40sp"/>
  154. </LinearLayout>  newContext = GlobalScope.newCoroutineContext(context)
  155.     }
  156.     val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop)
  157.     coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
  158.     return coroutine.joinBlocking()
  159. }
复制代码
​    说明:runBlocking 是一个顶层函数,用于启动一个新的协程并阻塞当前线程,直到协程执行完成; runBlocking 本质上是为了在顶层(如 main 函数)使用协程,以及在测试中使用协程;在生产代码中不保举使用 runBlocking,由于它会阻塞当前线程,大概导致性能问题。
3.3.4 withContext
  1. public suspend fun <T> withContext(
  2.     context: CoroutineContext,
  3.     block: suspend CoroutineScope.() -> T
  4. ): T {
  5.     // ...
  6.     return suspendCoroutineUninterceptedOrReturn sc@ { uCont ->
  7. <?xml version="1.0" encoding="utf-8"?>
  8. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  9.     xmlns:tools="http://schemas.android.com/tools"
  10.     android:layout_width="match_parent"
  11.     android:layout_height="match_parent"
  12.     tools:context=".MainActivity"
  13.     android:orientation="vertical"
  14.     android:gravity="center">
  15.    <ImageView
  16.        android:id="@+id/imageView"
  17.        android:layout_height="match_parent"
  18.        android:layout_width="match_parent"
  19.        android:scaleType="centerCrop"
  20.        android:visibility="gone" />
  21.    <Button
  22.        android:id="@+id/btn_back"
  23.        android:layout_width="250dp"
  24.        android:layout_height="wrap_content"
  25.        android:text="加载图片"
  26.        android:textSize="40sp"/>
  27. </LinearLayout>  val oldContext = uCont.context
  28. <?xml version="1.0" encoding="utf-8"?>
  29. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  30.     xmlns:tools="http://schemas.android.com/tools"
  31.     android:layout_width="match_parent"
  32.     android:layout_height="match_parent"
  33.     tools:context=".MainActivity"
  34.     android:orientation="vertical"
  35.     android:gravity="center">
  36.    <ImageView
  37.        android:id="@+id/imageView"
  38.        android:layout_height="match_parent"
  39.        android:layout_width="match_parent"
  40.        android:scaleType="centerCrop"
  41.        android:visibility="gone" />
  42.    <Button
  43.        android:id="@+id/btn_back"
  44.        android:layout_width="250dp"
  45.        android:layout_height="wrap_content"
  46.        android:text="加载图片"
  47.        android:textSize="40sp"/>
  48. </LinearLayout>  val newContext = oldContext.newCoroutineContext(context)
  49. <?xml version="1.0" encoding="utf-8"?>
  50. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  51.     xmlns:tools="http://schemas.android.com/tools"
  52.     android:layout_width="match_parent"
  53.     android:layout_height="match_parent"
  54.     tools:context=".MainActivity"
  55.     android:orientation="vertical"
  56.     android:gravity="center">
  57.    <ImageView
  58.        android:id="@+id/imageView"
  59.        android:layout_height="match_parent"
  60.        android:layout_width="match_parent"
  61.        android:scaleType="centerCrop"
  62.        android:visibility="gone" />
  63.    <Button
  64.        android:id="@+id/btn_back"
  65.        android:layout_width="250dp"
  66.        android:layout_height="wrap_content"
  67.        android:text="加载图片"
  68.        android:textSize="40sp"/>
  69. </LinearLayout>  newContext.ensureActive()
  70. <?xml version="1.0" encoding="utf-8"?>
  71. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  72.     xmlns:tools="http://schemas.android.com/tools"
  73.     android:layout_width="match_parent"
  74.     android:layout_height="match_parent"
  75.     tools:context=".MainActivity"
  76.     android:orientation="vertical"
  77.     android:gravity="center">
  78.    <ImageView
  79.        android:id="@+id/imageView"
  80.        android:layout_height="match_parent"
  81.        android:layout_width="match_parent"
  82.        android:scaleType="centerCrop"
  83.        android:visibility="gone" />
  84.    <Button
  85.        android:id="@+id/btn_back"
  86.        android:layout_width="250dp"
  87.        android:layout_height="wrap_content"
  88.        android:text="加载图片"
  89.        android:textSize="40sp"/>
  90. </LinearLayout>  if (newContext === oldContext) {
  91. <?xml version="1.0" encoding="utf-8"?>
  92. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  93.     xmlns:tools="http://schemas.android.com/tools"
  94.     android:layout_width="match_parent"
  95.     android:layout_height="match_parent"
  96.     tools:context=".MainActivity"
  97.     android:orientation="vertical"
  98.     android:gravity="center">
  99.    <ImageView
  100.        android:id="@+id/imageView"
  101.        android:layout_height="match_parent"
  102.        android:layout_width="match_parent"
  103.        android:scaleType="centerCrop"
  104.        android:visibility="gone" />
  105.    <Button
  106.        android:id="@+id/btn_back"
  107.        android:layout_width="250dp"
  108.        android:layout_height="wrap_content"
  109.        android:text="加载图片"
  110.        android:textSize="40sp"/>
  111. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  112. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  113.     xmlns:tools="http://schemas.android.com/tools"
  114.     android:layout_width="match_parent"
  115.     android:layout_height="match_parent"
  116.     tools:context=".MainActivity"
  117.     android:orientation="vertical"
  118.     android:gravity="center">
  119.    <ImageView
  120.        android:id="@+id/imageView"
  121.        android:layout_height="match_parent"
  122.        android:layout_width="match_parent"
  123.        android:scaleType="centerCrop"
  124.        android:visibility="gone" />
  125.    <Button
  126.        android:id="@+id/btn_back"
  127.        android:layout_width="250dp"
  128.        android:layout_height="wrap_content"
  129.        android:text="加载图片"
  130.        android:textSize="40sp"/>
  131. </LinearLayout>val coroutine = ScopeCoroutine(newContext, uCont)
  132. <?xml version="1.0" encoding="utf-8"?>
  133. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  134.     xmlns:tools="http://schemas.android.com/tools"
  135.     android:layout_width="match_parent"
  136.     android:layout_height="match_parent"
  137.     tools:context=".MainActivity"
  138.     android:orientation="vertical"
  139.     android:gravity="center">
  140.    <ImageView
  141.        android:id="@+id/imageView"
  142.        android:layout_height="match_parent"
  143.        android:layout_width="match_parent"
  144.        android:scaleType="centerCrop"
  145.        android:visibility="gone" />
  146.    <Button
  147.        android:id="@+id/btn_back"
  148.        android:layout_width="250dp"
  149.        android:layout_height="wrap_content"
  150.        android:text="加载图片"
  151.        android:textSize="40sp"/>
  152. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  153. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  154.     xmlns:tools="http://schemas.android.com/tools"
  155.     android:layout_width="match_parent"
  156.     android:layout_height="match_parent"
  157.     tools:context=".MainActivity"
  158.     android:orientation="vertical"
  159.     android:gravity="center">
  160.    <ImageView
  161.        android:id="@+id/imageView"
  162.        android:layout_height="match_parent"
  163.        android:layout_width="match_parent"
  164.        android:scaleType="centerCrop"
  165.        android:visibility="gone" />
  166.    <Button
  167.        android:id="@+id/btn_back"
  168.        android:layout_width="250dp"
  169.        android:layout_height="wrap_content"
  170.        android:text="加载图片"
  171.        android:textSize="40sp"/>
  172. </LinearLayout>return@sc coroutine.startUndispatchedOrReturn(coroutine, block)
  173. <?xml version="1.0" encoding="utf-8"?>
  174. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  175.     xmlns:tools="http://schemas.android.com/tools"
  176.     android:layout_width="match_parent"
  177.     android:layout_height="match_parent"
  178.     tools:context=".MainActivity"
  179.     android:orientation="vertical"
  180.     android:gravity="center">
  181.    <ImageView
  182.        android:id="@+id/imageView"
  183.        android:layout_height="match_parent"
  184.        android:layout_width="match_parent"
  185.        android:scaleType="centerCrop"
  186.        android:visibility="gone" />
  187.    <Button
  188.        android:id="@+id/btn_back"
  189.        android:layout_width="250dp"
  190.        android:layout_height="wrap_content"
  191.        android:text="加载图片"
  192.        android:textSize="40sp"/>
  193. </LinearLayout>  }
  194. <?xml version="1.0" encoding="utf-8"?>
  195. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  196.     xmlns:tools="http://schemas.android.com/tools"
  197.     android:layout_width="match_parent"
  198.     android:layout_height="match_parent"
  199.     tools:context=".MainActivity"
  200.     android:orientation="vertical"
  201.     android:gravity="center">
  202.    <ImageView
  203.        android:id="@+id/imageView"
  204.        android:layout_height="match_parent"
  205.        android:layout_width="match_parent"
  206.        android:scaleType="centerCrop"
  207.        android:visibility="gone" />
  208.    <Button
  209.        android:id="@+id/btn_back"
  210.        android:layout_width="250dp"
  211.        android:layout_height="wrap_content"
  212.        android:text="加载图片"
  213.        android:textSize="40sp"/>
  214. </LinearLayout>  if (newContext[ContinuationInterceptor] == oldContext[ContinuationInterceptor]) {
  215. <?xml version="1.0" encoding="utf-8"?>
  216. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  217.     xmlns:tools="http://schemas.android.com/tools"
  218.     android:layout_width="match_parent"
  219.     android:layout_height="match_parent"
  220.     tools:context=".MainActivity"
  221.     android:orientation="vertical"
  222.     android:gravity="center">
  223.    <ImageView
  224.        android:id="@+id/imageView"
  225.        android:layout_height="match_parent"
  226.        android:layout_width="match_parent"
  227.        android:scaleType="centerCrop"
  228.        android:visibility="gone" />
  229.    <Button
  230.        android:id="@+id/btn_back"
  231.        android:layout_width="250dp"
  232.        android:layout_height="wrap_content"
  233.        android:text="加载图片"
  234.        android:textSize="40sp"/>
  235. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  236. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  237.     xmlns:tools="http://schemas.android.com/tools"
  238.     android:layout_width="match_parent"
  239.     android:layout_height="match_parent"
  240.     tools:context=".MainActivity"
  241.     android:orientation="vertical"
  242.     android:gravity="center">
  243.    <ImageView
  244.        android:id="@+id/imageView"
  245.        android:layout_height="match_parent"
  246.        android:layout_width="match_parent"
  247.        android:scaleType="centerCrop"
  248.        android:visibility="gone" />
  249.    <Button
  250.        android:id="@+id/btn_back"
  251.        android:layout_width="250dp"
  252.        android:layout_height="wrap_content"
  253.        android:text="加载图片"
  254.        android:textSize="40sp"/>
  255. </LinearLayout>val coroutine = UndispatchedCoroutine(newContext, uCont)
  256. <?xml version="1.0" encoding="utf-8"?>
  257. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  258.     xmlns:tools="http://schemas.android.com/tools"
  259.     android:layout_width="match_parent"
  260.     android:layout_height="match_parent"
  261.     tools:context=".MainActivity"
  262.     android:orientation="vertical"
  263.     android:gravity="center">
  264.    <ImageView
  265.        android:id="@+id/imageView"
  266.        android:layout_height="match_parent"
  267.        android:layout_width="match_parent"
  268.        android:scaleType="centerCrop"
  269.        android:visibility="gone" />
  270.    <Button
  271.        android:id="@+id/btn_back"
  272.        android:layout_width="250dp"
  273.        android:layout_height="wrap_content"
  274.        android:text="加载图片"
  275.        android:textSize="40sp"/>
  276. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  277. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  278.     xmlns:tools="http://schemas.android.com/tools"
  279.     android:layout_width="match_parent"
  280.     android:layout_height="match_parent"
  281.     tools:context=".MainActivity"
  282.     android:orientation="vertical"
  283.     android:gravity="center">
  284.    <ImageView
  285.        android:id="@+id/imageView"
  286.        android:layout_height="match_parent"
  287.        android:layout_width="match_parent"
  288.        android:scaleType="centerCrop"
  289.        android:visibility="gone" />
  290.    <Button
  291.        android:id="@+id/btn_back"
  292.        android:layout_width="250dp"
  293.        android:layout_height="wrap_content"
  294.        android:text="加载图片"
  295.        android:textSize="40sp"/>
  296. </LinearLayout>withCoroutineContext(newContext, null) {
  297. <?xml version="1.0" encoding="utf-8"?>
  298. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  299.     xmlns:tools="http://schemas.android.com/tools"
  300.     android:layout_width="match_parent"
  301.     android:layout_height="match_parent"
  302.     tools:context=".MainActivity"
  303.     android:orientation="vertical"
  304.     android:gravity="center">
  305.    <ImageView
  306.        android:id="@+id/imageView"
  307.        android:layout_height="match_parent"
  308.        android:layout_width="match_parent"
  309.        android:scaleType="centerCrop"
  310.        android:visibility="gone" />
  311.    <Button
  312.        android:id="@+id/btn_back"
  313.        android:layout_width="250dp"
  314.        android:layout_height="wrap_content"
  315.        android:text="加载图片"
  316.        android:textSize="40sp"/>
  317. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  318. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  319.     xmlns:tools="http://schemas.android.com/tools"
  320.     android:layout_width="match_parent"
  321.     android:layout_height="match_parent"
  322.     tools:context=".MainActivity"
  323.     android:orientation="vertical"
  324.     android:gravity="center">
  325.    <ImageView
  326.        android:id="@+id/imageView"
  327.        android:layout_height="match_parent"
  328.        android:layout_width="match_parent"
  329.        android:scaleType="centerCrop"
  330.        android:visibility="gone" />
  331.    <Button
  332.        android:id="@+id/btn_back"
  333.        android:layout_width="250dp"
  334.        android:layout_height="wrap_content"
  335.        android:text="加载图片"
  336.        android:textSize="40sp"/>
  337. </LinearLayout>    return@sc coroutine.startUndispatchedOrReturn(coroutine, block)
  338. <?xml version="1.0" encoding="utf-8"?>
  339. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  340.     xmlns:tools="http://schemas.android.com/tools"
  341.     android:layout_width="match_parent"
  342.     android:layout_height="match_parent"
  343.     tools:context=".MainActivity"
  344.     android:orientation="vertical"
  345.     android:gravity="center">
  346.    <ImageView
  347.        android:id="@+id/imageView"
  348.        android:layout_height="match_parent"
  349.        android:layout_width="match_parent"
  350.        android:scaleType="centerCrop"
  351.        android:visibility="gone" />
  352.    <Button
  353.        android:id="@+id/btn_back"
  354.        android:layout_width="250dp"
  355.        android:layout_height="wrap_content"
  356.        android:text="加载图片"
  357.        android:textSize="40sp"/>
  358. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  359. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  360.     xmlns:tools="http://schemas.android.com/tools"
  361.     android:layout_width="match_parent"
  362.     android:layout_height="match_parent"
  363.     tools:context=".MainActivity"
  364.     android:orientation="vertical"
  365.     android:gravity="center">
  366.    <ImageView
  367.        android:id="@+id/imageView"
  368.        android:layout_height="match_parent"
  369.        android:layout_width="match_parent"
  370.        android:scaleType="centerCrop"
  371.        android:visibility="gone" />
  372.    <Button
  373.        android:id="@+id/btn_back"
  374.        android:layout_width="250dp"
  375.        android:layout_height="wrap_content"
  376.        android:text="加载图片"
  377.        android:textSize="40sp"/>
  378. </LinearLayout>}
  379. <?xml version="1.0" encoding="utf-8"?>
  380. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  381.     xmlns:tools="http://schemas.android.com/tools"
  382.     android:layout_width="match_parent"
  383.     android:layout_height="match_parent"
  384.     tools:context=".MainActivity"
  385.     android:orientation="vertical"
  386.     android:gravity="center">
  387.    <ImageView
  388.        android:id="@+id/imageView"
  389.        android:layout_height="match_parent"
  390.        android:layout_width="match_parent"
  391.        android:scaleType="centerCrop"
  392.        android:visibility="gone" />
  393.    <Button
  394.        android:id="@+id/btn_back"
  395.        android:layout_width="250dp"
  396.        android:layout_height="wrap_content"
  397.        android:text="加载图片"
  398.        android:textSize="40sp"/>
  399. </LinearLayout>  }
  400. <?xml version="1.0" encoding="utf-8"?>
  401. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  402.     xmlns:tools="http://schemas.android.com/tools"
  403.     android:layout_width="match_parent"
  404.     android:layout_height="match_parent"
  405.     tools:context=".MainActivity"
  406.     android:orientation="vertical"
  407.     android:gravity="center">
  408.    <ImageView
  409.        android:id="@+id/imageView"
  410.        android:layout_height="match_parent"
  411.        android:layout_width="match_parent"
  412.        android:scaleType="centerCrop"
  413.        android:visibility="gone" />
  414.    <Button
  415.        android:id="@+id/btn_back"
  416.        android:layout_width="250dp"
  417.        android:layout_height="wrap_content"
  418.        android:text="加载图片"
  419.        android:textSize="40sp"/>
  420. </LinearLayout>  val coroutine = DispatchedCoroutine(newContext, uCont)
  421. <?xml version="1.0" encoding="utf-8"?>
  422. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  423.     xmlns:tools="http://schemas.android.com/tools"
  424.     android:layout_width="match_parent"
  425.     android:layout_height="match_parent"
  426.     tools:context=".MainActivity"
  427.     android:orientation="vertical"
  428.     android:gravity="center">
  429.    <ImageView
  430.        android:id="@+id/imageView"
  431.        android:layout_height="match_parent"
  432.        android:layout_width="match_parent"
  433.        android:scaleType="centerCrop"
  434.        android:visibility="gone" />
  435.    <Button
  436.        android:id="@+id/btn_back"
  437.        android:layout_width="250dp"
  438.        android:layout_height="wrap_content"
  439.        android:text="加载图片"
  440.        android:textSize="40sp"/>
  441. </LinearLayout>  block.startCoroutineCancellable(coroutine, coroutine)
  442. <?xml version="1.0" encoding="utf-8"?>
  443. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  444.     xmlns:tools="http://schemas.android.com/tools"
  445.     android:layout_width="match_parent"
  446.     android:layout_height="match_parent"
  447.     tools:context=".MainActivity"
  448.     android:orientation="vertical"
  449.     android:gravity="center">
  450.    <ImageView
  451.        android:id="@+id/imageView"
  452.        android:layout_height="match_parent"
  453.        android:layout_width="match_parent"
  454.        android:scaleType="centerCrop"
  455.        android:visibility="gone" />
  456.    <Button
  457.        android:id="@+id/btn_back"
  458.        android:layout_width="250dp"
  459.        android:layout_height="wrap_content"
  460.        android:text="加载图片"
  461.        android:textSize="40sp"/>
  462. </LinearLayout>  coroutine.getResult()
  463.     }
  464. }
复制代码
​    说明:withContext 用于切换协程的上下文,它会创建一个新的协程并在指定的上下文中执行,它会挂起原来的协程,待新协程执行结束后才恢复执行。
3.4 协程启动模式源码(CoroutineStart)
  1. public enum class CoroutineStart {
  2.         // 立即执行协程体
  3.     DEFAULT,
  4.     // 只有在需要的情况下运行, 需要调用job.start()函数才启动协程
  5.     LAZY,
  6.     // 立即执行协程体, 但在开始运行前无法取消
  7.     ATOMIC,
  8.     // 立即在当前线程执行协程体, 直到第一个suspend函数调用(启动较快)
  9.     UNDISPATCHED;
  10.     // ...
  11. }
复制代码
4 协程应用

4.1 协程作用域应用

4.1.1 CoroutineScope
  1. fun main() {
  2.     println("main-start")
  3.     CoroutineScope(Dispatchers.Default).launch {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  for (i in 1..2) {
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  46. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  47.     xmlns:tools="http://schemas.android.com/tools"
  48.     android:layout_width="match_parent"
  49.     android:layout_height="match_parent"
  50.     tools:context=".MainActivity"
  51.     android:orientation="vertical"
  52.     android:gravity="center">
  53.    <ImageView
  54.        android:id="@+id/imageView"
  55.        android:layout_height="match_parent"
  56.        android:layout_width="match_parent"
  57.        android:scaleType="centerCrop"
  58.        android:visibility="gone" />
  59.    <Button
  60.        android:id="@+id/btn_back"
  61.        android:layout_width="250dp"
  62.        android:layout_height="wrap_content"
  63.        android:text="加载图片"
  64.        android:textSize="40sp"/>
  65. </LinearLayout>println("CoroutineScope-A-$i")
  66. <?xml version="1.0" encoding="utf-8"?>
  67. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  68.     xmlns:tools="http://schemas.android.com/tools"
  69.     android:layout_width="match_parent"
  70.     android:layout_height="match_parent"
  71.     tools:context=".MainActivity"
  72.     android:orientation="vertical"
  73.     android:gravity="center">
  74.    <ImageView
  75.        android:id="@+id/imageView"
  76.        android:layout_height="match_parent"
  77.        android:layout_width="match_parent"
  78.        android:scaleType="centerCrop"
  79.        android:visibility="gone" />
  80.    <Button
  81.        android:id="@+id/btn_back"
  82.        android:layout_width="250dp"
  83.        android:layout_height="wrap_content"
  84.        android:text="加载图片"
  85.        android:textSize="40sp"/>
  86. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  87. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  88.     xmlns:tools="http://schemas.android.com/tools"
  89.     android:layout_width="match_parent"
  90.     android:layout_height="match_parent"
  91.     tools:context=".MainActivity"
  92.     android:orientation="vertical"
  93.     android:gravity="center">
  94.    <ImageView
  95.        android:id="@+id/imageView"
  96.        android:layout_height="match_parent"
  97.        android:layout_width="match_parent"
  98.        android:scaleType="centerCrop"
  99.        android:visibility="gone" />
  100.    <Button
  101.        android:id="@+id/btn_back"
  102.        android:layout_width="250dp"
  103.        android:layout_height="wrap_content"
  104.        android:text="加载图片"
  105.        android:textSize="40sp"/>
  106. </LinearLayout>delay(100)
  107. <?xml version="1.0" encoding="utf-8"?>
  108. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  109.     xmlns:tools="http://schemas.android.com/tools"
  110.     android:layout_width="match_parent"
  111.     android:layout_height="match_parent"
  112.     tools:context=".MainActivity"
  113.     android:orientation="vertical"
  114.     android:gravity="center">
  115.    <ImageView
  116.        android:id="@+id/imageView"
  117.        android:layout_height="match_parent"
  118.        android:layout_width="match_parent"
  119.        android:scaleType="centerCrop"
  120.        android:visibility="gone" />
  121.    <Button
  122.        android:id="@+id/btn_back"
  123.        android:layout_width="250dp"
  124.        android:layout_height="wrap_content"
  125.        android:text="加载图片"
  126.        android:textSize="40sp"/>
  127. </LinearLayout>  }
  128.     }
  129.     CoroutineScope(Dispatchers.IO).launch {
  130. <?xml version="1.0" encoding="utf-8"?>
  131. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  132.     xmlns:tools="http://schemas.android.com/tools"
  133.     android:layout_width="match_parent"
  134.     android:layout_height="match_parent"
  135.     tools:context=".MainActivity"
  136.     android:orientation="vertical"
  137.     android:gravity="center">
  138.    <ImageView
  139.        android:id="@+id/imageView"
  140.        android:layout_height="match_parent"
  141.        android:layout_width="match_parent"
  142.        android:scaleType="centerCrop"
  143.        android:visibility="gone" />
  144.    <Button
  145.        android:id="@+id/btn_back"
  146.        android:layout_width="250dp"
  147.        android:layout_height="wrap_content"
  148.        android:text="加载图片"
  149.        android:textSize="40sp"/>
  150. </LinearLayout>  for (i in 1..2) {
  151. <?xml version="1.0" encoding="utf-8"?>
  152. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  153.     xmlns:tools="http://schemas.android.com/tools"
  154.     android:layout_width="match_parent"
  155.     android:layout_height="match_parent"
  156.     tools:context=".MainActivity"
  157.     android:orientation="vertical"
  158.     android:gravity="center">
  159.    <ImageView
  160.        android:id="@+id/imageView"
  161.        android:layout_height="match_parent"
  162.        android:layout_width="match_parent"
  163.        android:scaleType="centerCrop"
  164.        android:visibility="gone" />
  165.    <Button
  166.        android:id="@+id/btn_back"
  167.        android:layout_width="250dp"
  168.        android:layout_height="wrap_content"
  169.        android:text="加载图片"
  170.        android:textSize="40sp"/>
  171. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  172. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  173.     xmlns:tools="http://schemas.android.com/tools"
  174.     android:layout_width="match_parent"
  175.     android:layout_height="match_parent"
  176.     tools:context=".MainActivity"
  177.     android:orientation="vertical"
  178.     android:gravity="center">
  179.    <ImageView
  180.        android:id="@+id/imageView"
  181.        android:layout_height="match_parent"
  182.        android:layout_width="match_parent"
  183.        android:scaleType="centerCrop"
  184.        android:visibility="gone" />
  185.    <Button
  186.        android:id="@+id/btn_back"
  187.        android:layout_width="250dp"
  188.        android:layout_height="wrap_content"
  189.        android:text="加载图片"
  190.        android:textSize="40sp"/>
  191. </LinearLayout>println("CoroutineScope-B-$i")
  192. <?xml version="1.0" encoding="utf-8"?>
  193. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  194.     xmlns:tools="http://schemas.android.com/tools"
  195.     android:layout_width="match_parent"
  196.     android:layout_height="match_parent"
  197.     tools:context=".MainActivity"
  198.     android:orientation="vertical"
  199.     android:gravity="center">
  200.    <ImageView
  201.        android:id="@+id/imageView"
  202.        android:layout_height="match_parent"
  203.        android:layout_width="match_parent"
  204.        android:scaleType="centerCrop"
  205.        android:visibility="gone" />
  206.    <Button
  207.        android:id="@+id/btn_back"
  208.        android:layout_width="250dp"
  209.        android:layout_height="wrap_content"
  210.        android:text="加载图片"
  211.        android:textSize="40sp"/>
  212. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  213. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  214.     xmlns:tools="http://schemas.android.com/tools"
  215.     android:layout_width="match_parent"
  216.     android:layout_height="match_parent"
  217.     tools:context=".MainActivity"
  218.     android:orientation="vertical"
  219.     android:gravity="center">
  220.    <ImageView
  221.        android:id="@+id/imageView"
  222.        android:layout_height="match_parent"
  223.        android:layout_width="match_parent"
  224.        android:scaleType="centerCrop"
  225.        android:visibility="gone" />
  226.    <Button
  227.        android:id="@+id/btn_back"
  228.        android:layout_width="250dp"
  229.        android:layout_height="wrap_content"
  230.        android:text="加载图片"
  231.        android:textSize="40sp"/>
  232. </LinearLayout>delay(100)
  233. <?xml version="1.0" encoding="utf-8"?>
  234. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  235.     xmlns:tools="http://schemas.android.com/tools"
  236.     android:layout_width="match_parent"
  237.     android:layout_height="match_parent"
  238.     tools:context=".MainActivity"
  239.     android:orientation="vertical"
  240.     android:gravity="center">
  241.    <ImageView
  242.        android:id="@+id/imageView"
  243.        android:layout_height="match_parent"
  244.        android:layout_width="match_parent"
  245.        android:scaleType="centerCrop"
  246.        android:visibility="gone" />
  247.    <Button
  248.        android:id="@+id/btn_back"
  249.        android:layout_width="250dp"
  250.        android:layout_height="wrap_content"
  251.        android:text="加载图片"
  252.        android:textSize="40sp"/>
  253. </LinearLayout>  }
  254.     }
  255.     println("main-end")
  256.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  257. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. CoroutineScope-A-1
  4. CoroutineScope-B-1
  5. CoroutineScope-A-2
  6. CoroutineScope-B-2
复制代码
​    说明:结果表明 main、CoroutineScope-A、CoroutineScope-B 并行。
4.1.2 MainScope
  1. fun main() {
  2.     println("main-start")
  3.     MainScope().launch(Dispatchers.Default) {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  test("MainScope-A")
  25.     }
  26.     MainScope().launch(Dispatchers.IO) {
  27. <?xml version="1.0" encoding="utf-8"?>
  28. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  29.     xmlns:tools="http://schemas.android.com/tools"
  30.     android:layout_width="match_parent"
  31.     android:layout_height="match_parent"
  32.     tools:context=".MainActivity"
  33.     android:orientation="vertical"
  34.     android:gravity="center">
  35.    <ImageView
  36.        android:id="@+id/imageView"
  37.        android:layout_height="match_parent"
  38.        android:layout_width="match_parent"
  39.        android:scaleType="centerCrop"
  40.        android:visibility="gone" />
  41.    <Button
  42.        android:id="@+id/btn_back"
  43.        android:layout_width="250dp"
  44.        android:layout_height="wrap_content"
  45.        android:text="加载图片"
  46.        android:textSize="40sp"/>
  47. </LinearLayout>  test("MainScope-B")
  48.     }
  49.     println("main-end")
  50.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  51. }
  52. suspend fun test(tag: String) {
  53.     for (i in 1..2) {
  54. <?xml version="1.0" encoding="utf-8"?>
  55. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  56.     xmlns:tools="http://schemas.android.com/tools"
  57.     android:layout_width="match_parent"
  58.     android:layout_height="match_parent"
  59.     tools:context=".MainActivity"
  60.     android:orientation="vertical"
  61.     android:gravity="center">
  62.    <ImageView
  63.        android:id="@+id/imageView"
  64.        android:layout_height="match_parent"
  65.        android:layout_width="match_parent"
  66.        android:scaleType="centerCrop"
  67.        android:visibility="gone" />
  68.    <Button
  69.        android:id="@+id/btn_back"
  70.        android:layout_width="250dp"
  71.        android:layout_height="wrap_content"
  72.        android:text="加载图片"
  73.        android:textSize="40sp"/>
  74. </LinearLayout>  println("$tag-$i")
  75. <?xml version="1.0" encoding="utf-8"?>
  76. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  77.     xmlns:tools="http://schemas.android.com/tools"
  78.     android:layout_width="match_parent"
  79.     android:layout_height="match_parent"
  80.     tools:context=".MainActivity"
  81.     android:orientation="vertical"
  82.     android:gravity="center">
  83.    <ImageView
  84.        android:id="@+id/imageView"
  85.        android:layout_height="match_parent"
  86.        android:layout_width="match_parent"
  87.        android:scaleType="centerCrop"
  88.        android:visibility="gone" />
  89.    <Button
  90.        android:id="@+id/btn_back"
  91.        android:layout_width="250dp"
  92.        android:layout_height="wrap_content"
  93.        android:text="加载图片"
  94.        android:textSize="40sp"/>
  95. </LinearLayout>  delay(100)
  96.     }
  97. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. MainScope-B-1
  4. MainScope-A-1
  5. MainScope-A-2
  6. MainScope-B-2
复制代码
​    说明:结果表明 main、MainScope-A、MainScope-B 并行。
4.1.3 GlobalScope
  1. fun main() {
  2.     println("main-start")
  3.     GlobalScope.launch(Dispatchers.Default, CoroutineStart.DEFAULT) {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  test("GlobalScope-A")
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout>  test("GlobalScope-B")
  46.     }
  47.     println("main-end")
  48.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  49. }
  50. suspend fun test(tag: String) {
  51.     for (i in 1..2) {
  52. <?xml version="1.0" encoding="utf-8"?>
  53. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  54.     xmlns:tools="http://schemas.android.com/tools"
  55.     android:layout_width="match_parent"
  56.     android:layout_height="match_parent"
  57.     tools:context=".MainActivity"
  58.     android:orientation="vertical"
  59.     android:gravity="center">
  60.    <ImageView
  61.        android:id="@+id/imageView"
  62.        android:layout_height="match_parent"
  63.        android:layout_width="match_parent"
  64.        android:scaleType="centerCrop"
  65.        android:visibility="gone" />
  66.    <Button
  67.        android:id="@+id/btn_back"
  68.        android:layout_width="250dp"
  69.        android:layout_height="wrap_content"
  70.        android:text="加载图片"
  71.        android:textSize="40sp"/>
  72. </LinearLayout>  println("$tag-$i")
  73. <?xml version="1.0" encoding="utf-8"?>
  74. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  75.     xmlns:tools="http://schemas.android.com/tools"
  76.     android:layout_width="match_parent"
  77.     android:layout_height="match_parent"
  78.     tools:context=".MainActivity"
  79.     android:orientation="vertical"
  80.     android:gravity="center">
  81.    <ImageView
  82.        android:id="@+id/imageView"
  83.        android:layout_height="match_parent"
  84.        android:layout_width="match_parent"
  85.        android:scaleType="centerCrop"
  86.        android:visibility="gone" />
  87.    <Button
  88.        android:id="@+id/btn_back"
  89.        android:layout_width="250dp"
  90.        android:layout_height="wrap_content"
  91.        android:text="加载图片"
  92.        android:textSize="40sp"/>
  93. </LinearLayout>  delay(100)
  94.     }
  95. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. GlobalScope-A-1
  4. GlobalScope-A-2
  5. GlobalScope-B-1
  6. GlobalScope-B-2
复制代码
​    说明:结果表明 main 与 GlobalScope 并行。
4.1.4 lifecycleScope
  1. import android.os.Bundle
  2. import androidx.appcompat.app.AppCompatActivity
  3. import androidx.lifecycle.lifecycleScope
  4. import kotlinx.coroutines.launch
  5. class MyActivity: AppCompatActivity() {
  6.     override fun onCreate(savedInstanceState: Bundle?) {
  7. <?xml version="1.0" encoding="utf-8"?>
  8. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  9.     xmlns:tools="http://schemas.android.com/tools"
  10.     android:layout_width="match_parent"
  11.     android:layout_height="match_parent"
  12.     tools:context=".MainActivity"
  13.     android:orientation="vertical"
  14.     android:gravity="center">
  15.    <ImageView
  16.        android:id="@+id/imageView"
  17.        android:layout_height="match_parent"
  18.        android:layout_width="match_parent"
  19.        android:scaleType="centerCrop"
  20.        android:visibility="gone" />
  21.    <Button
  22.        android:id="@+id/btn_back"
  23.        android:layout_width="250dp"
  24.        android:layout_height="wrap_content"
  25.        android:text="加载图片"
  26.        android:textSize="40sp"/>
  27. </LinearLayout>  super.onCreate(savedInstanceState)
  28. <?xml version="1.0" encoding="utf-8"?>
  29. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  30.     xmlns:tools="http://schemas.android.com/tools"
  31.     android:layout_width="match_parent"
  32.     android:layout_height="match_parent"
  33.     tools:context=".MainActivity"
  34.     android:orientation="vertical"
  35.     android:gravity="center">
  36.    <ImageView
  37.        android:id="@+id/imageView"
  38.        android:layout_height="match_parent"
  39.        android:layout_width="match_parent"
  40.        android:scaleType="centerCrop"
  41.        android:visibility="gone" />
  42.    <Button
  43.        android:id="@+id/btn_back"
  44.        android:layout_width="250dp"
  45.        android:layout_height="wrap_content"
  46.        android:text="加载图片"
  47.        android:textSize="40sp"/>
  48. </LinearLayout>  setContentView(R.layout.activity_main)
  49. <?xml version="1.0" encoding="utf-8"?>
  50. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  51.     xmlns:tools="http://schemas.android.com/tools"
  52.     android:layout_width="match_parent"
  53.     android:layout_height="match_parent"
  54.     tools:context=".MainActivity"
  55.     android:orientation="vertical"
  56.     android:gravity="center">
  57.    <ImageView
  58.        android:id="@+id/imageView"
  59.        android:layout_height="match_parent"
  60.        android:layout_width="match_parent"
  61.        android:scaleType="centerCrop"
  62.        android:visibility="gone" />
  63.    <Button
  64.        android:id="@+id/btn_back"
  65.        android:layout_width="250dp"
  66.        android:layout_height="wrap_content"
  67.        android:text="加载图片"
  68.        android:textSize="40sp"/>
  69. </LinearLayout>  lifecycleScope.launch {
  70. <?xml version="1.0" encoding="utf-8"?>
  71. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  72.     xmlns:tools="http://schemas.android.com/tools"
  73.     android:layout_width="match_parent"
  74.     android:layout_height="match_parent"
  75.     tools:context=".MainActivity"
  76.     android:orientation="vertical"
  77.     android:gravity="center">
  78.    <ImageView
  79.        android:id="@+id/imageView"
  80.        android:layout_height="match_parent"
  81.        android:layout_width="match_parent"
  82.        android:scaleType="centerCrop"
  83.        android:visibility="gone" />
  84.    <Button
  85.        android:id="@+id/btn_back"
  86.        android:layout_width="250dp"
  87.        android:layout_height="wrap_content"
  88.        android:text="加载图片"
  89.        android:textSize="40sp"/>
  90. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  91. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  92.     xmlns:tools="http://schemas.android.com/tools"
  93.     android:layout_width="match_parent"
  94.     android:layout_height="match_parent"
  95.     tools:context=".MainActivity"
  96.     android:orientation="vertical"
  97.     android:gravity="center">
  98.    <ImageView
  99.        android:id="@+id/imageView"
  100.        android:layout_height="match_parent"
  101.        android:layout_width="match_parent"
  102.        android:scaleType="centerCrop"
  103.        android:visibility="gone" />
  104.    <Button
  105.        android:id="@+id/btn_back"
  106.        android:layout_width="250dp"
  107.        android:layout_height="wrap_content"
  108.        android:text="加载图片"
  109.        android:textSize="40sp"/>
  110. </LinearLayout>println("lifecycleScope")
  111. <?xml version="1.0" encoding="utf-8"?>
  112. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  113.     xmlns:tools="http://schemas.android.com/tools"
  114.     android:layout_width="match_parent"
  115.     android:layout_height="match_parent"
  116.     tools:context=".MainActivity"
  117.     android:orientation="vertical"
  118.     android:gravity="center">
  119.    <ImageView
  120.        android:id="@+id/imageView"
  121.        android:layout_height="match_parent"
  122.        android:layout_width="match_parent"
  123.        android:scaleType="centerCrop"
  124.        android:visibility="gone" />
  125.    <Button
  126.        android:id="@+id/btn_back"
  127.        android:layout_width="250dp"
  128.        android:layout_height="wrap_content"
  129.        android:text="加载图片"
  130.        android:textSize="40sp"/>
  131. </LinearLayout>  }
  132.     }
  133. }
复制代码
​    说明:使用 lifecycleScope 时,需要在 build.gradle 中引入以下依赖。
  1. implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
复制代码
4.1.5 viewModelScope
  1. import androidx.lifecycle.ViewModel
  2. import androidx.lifecycle.viewModelScope
  3. import kotlinx.coroutines.launch
  4. class MyViewModel: ViewModel() {
  5.     init {
  6. <?xml version="1.0" encoding="utf-8"?>
  7. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  8.     xmlns:tools="http://schemas.android.com/tools"
  9.     android:layout_width="match_parent"
  10.     android:layout_height="match_parent"
  11.     tools:context=".MainActivity"
  12.     android:orientation="vertical"
  13.     android:gravity="center">
  14.    <ImageView
  15.        android:id="@+id/imageView"
  16.        android:layout_height="match_parent"
  17.        android:layout_width="match_parent"
  18.        android:scaleType="centerCrop"
  19.        android:visibility="gone" />
  20.    <Button
  21.        android:id="@+id/btn_back"
  22.        android:layout_width="250dp"
  23.        android:layout_height="wrap_content"
  24.        android:text="加载图片"
  25.        android:textSize="40sp"/>
  26. </LinearLayout>  viewModelScope.launch {
  27. <?xml version="1.0" encoding="utf-8"?>
  28. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  29.     xmlns:tools="http://schemas.android.com/tools"
  30.     android:layout_width="match_parent"
  31.     android:layout_height="match_parent"
  32.     tools:context=".MainActivity"
  33.     android:orientation="vertical"
  34.     android:gravity="center">
  35.    <ImageView
  36.        android:id="@+id/imageView"
  37.        android:layout_height="match_parent"
  38.        android:layout_width="match_parent"
  39.        android:scaleType="centerCrop"
  40.        android:visibility="gone" />
  41.    <Button
  42.        android:id="@+id/btn_back"
  43.        android:layout_width="250dp"
  44.        android:layout_height="wrap_content"
  45.        android:text="加载图片"
  46.        android:textSize="40sp"/>
  47. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  48. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  49.     xmlns:tools="http://schemas.android.com/tools"
  50.     android:layout_width="match_parent"
  51.     android:layout_height="match_parent"
  52.     tools:context=".MainActivity"
  53.     android:orientation="vertical"
  54.     android:gravity="center">
  55.    <ImageView
  56.        android:id="@+id/imageView"
  57.        android:layout_height="match_parent"
  58.        android:layout_width="match_parent"
  59.        android:scaleType="centerCrop"
  60.        android:visibility="gone" />
  61.    <Button
  62.        android:id="@+id/btn_back"
  63.        android:layout_width="250dp"
  64.        android:layout_height="wrap_content"
  65.        android:text="加载图片"
  66.        android:textSize="40sp"/>
  67. </LinearLayout>println("viewModelScope")
  68. <?xml version="1.0" encoding="utf-8"?>
  69. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  70.     xmlns:tools="http://schemas.android.com/tools"
  71.     android:layout_width="match_parent"
  72.     android:layout_height="match_parent"
  73.     tools:context=".MainActivity"
  74.     android:orientation="vertical"
  75.     android:gravity="center">
  76.    <ImageView
  77.        android:id="@+id/imageView"
  78.        android:layout_height="match_parent"
  79.        android:layout_width="match_parent"
  80.        android:scaleType="centerCrop"
  81.        android:visibility="gone" />
  82.    <Button
  83.        android:id="@+id/btn_back"
  84.        android:layout_width="250dp"
  85.        android:layout_height="wrap_content"
  86.        android:text="加载图片"
  87.        android:textSize="40sp"/>
  88. </LinearLayout>  }
  89.     }
  90. }
复制代码
​    说明:使用 viewModelScope 时,需要在 build.gradle 中引入以下依赖。
  1. implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
复制代码
4.1.6 子协程
  1. fun main() {
  2.     println("main-start")
  3.     CoroutineScope(Dispatchers.Default).launch {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  test("CoroutineScope-A")
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout>  launch(Dispatchers.Default) { // 也可以通过async启动子协程
  46. <?xml version="1.0" encoding="utf-8"?>
  47. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  48.     xmlns:tools="http://schemas.android.com/tools"
  49.     android:layout_width="match_parent"
  50.     android:layout_height="match_parent"
  51.     tools:context=".MainActivity"
  52.     android:orientation="vertical"
  53.     android:gravity="center">
  54.    <ImageView
  55.        android:id="@+id/imageView"
  56.        android:layout_height="match_parent"
  57.        android:layout_width="match_parent"
  58.        android:scaleType="centerCrop"
  59.        android:visibility="gone" />
  60.    <Button
  61.        android:id="@+id/btn_back"
  62.        android:layout_width="250dp"
  63.        android:layout_height="wrap_content"
  64.        android:text="加载图片"
  65.        android:textSize="40sp"/>
  66. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  67. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  68.     xmlns:tools="http://schemas.android.com/tools"
  69.     android:layout_width="match_parent"
  70.     android:layout_height="match_parent"
  71.     tools:context=".MainActivity"
  72.     android:orientation="vertical"
  73.     android:gravity="center">
  74.    <ImageView
  75.        android:id="@+id/imageView"
  76.        android:layout_height="match_parent"
  77.        android:layout_width="match_parent"
  78.        android:scaleType="centerCrop"
  79.        android:visibility="gone" />
  80.    <Button
  81.        android:id="@+id/btn_back"
  82.        android:layout_width="250dp"
  83.        android:layout_height="wrap_content"
  84.        android:text="加载图片"
  85.        android:textSize="40sp"/>
  86. </LinearLayout>test("CoroutineScope-B")
  87. <?xml version="1.0" encoding="utf-8"?>
  88. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  89.     xmlns:tools="http://schemas.android.com/tools"
  90.     android:layout_width="match_parent"
  91.     android:layout_height="match_parent"
  92.     tools:context=".MainActivity"
  93.     android:orientation="vertical"
  94.     android:gravity="center">
  95.    <ImageView
  96.        android:id="@+id/imageView"
  97.        android:layout_height="match_parent"
  98.        android:layout_width="match_parent"
  99.        android:scaleType="centerCrop"
  100.        android:visibility="gone" />
  101.    <Button
  102.        android:id="@+id/btn_back"
  103.        android:layout_width="250dp"
  104.        android:layout_height="wrap_content"
  105.        android:text="加载图片"
  106.        android:textSize="40sp"/>
  107. </LinearLayout>  }
  108. <?xml version="1.0" encoding="utf-8"?>
  109. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  110.     xmlns:tools="http://schemas.android.com/tools"
  111.     android:layout_width="match_parent"
  112.     android:layout_height="match_parent"
  113.     tools:context=".MainActivity"
  114.     android:orientation="vertical"
  115.     android:gravity="center">
  116.    <ImageView
  117.        android:id="@+id/imageView"
  118.        android:layout_height="match_parent"
  119.        android:layout_width="match_parent"
  120.        android:scaleType="centerCrop"
  121.        android:visibility="gone" />
  122.    <Button
  123.        android:id="@+id/btn_back"
  124.        android:layout_width="250dp"
  125.        android:layout_height="wrap_content"
  126.        android:text="加载图片"
  127.        android:textSize="40sp"/>
  128. </LinearLayout>  launch(Dispatchers.Default) { // 也可以通过async启动子协程
  129. <?xml version="1.0" encoding="utf-8"?>
  130. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  131.     xmlns:tools="http://schemas.android.com/tools"
  132.     android:layout_width="match_parent"
  133.     android:layout_height="match_parent"
  134.     tools:context=".MainActivity"
  135.     android:orientation="vertical"
  136.     android:gravity="center">
  137.    <ImageView
  138.        android:id="@+id/imageView"
  139.        android:layout_height="match_parent"
  140.        android:layout_width="match_parent"
  141.        android:scaleType="centerCrop"
  142.        android:visibility="gone" />
  143.    <Button
  144.        android:id="@+id/btn_back"
  145.        android:layout_width="250dp"
  146.        android:layout_height="wrap_content"
  147.        android:text="加载图片"
  148.        android:textSize="40sp"/>
  149. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  150. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  151.     xmlns:tools="http://schemas.android.com/tools"
  152.     android:layout_width="match_parent"
  153.     android:layout_height="match_parent"
  154.     tools:context=".MainActivity"
  155.     android:orientation="vertical"
  156.     android:gravity="center">
  157.    <ImageView
  158.        android:id="@+id/imageView"
  159.        android:layout_height="match_parent"
  160.        android:layout_width="match_parent"
  161.        android:scaleType="centerCrop"
  162.        android:visibility="gone" />
  163.    <Button
  164.        android:id="@+id/btn_back"
  165.        android:layout_width="250dp"
  166.        android:layout_height="wrap_content"
  167.        android:text="加载图片"
  168.        android:textSize="40sp"/>
  169. </LinearLayout>test("CoroutineScope-C")
  170. <?xml version="1.0" encoding="utf-8"?>
  171. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  172.     xmlns:tools="http://schemas.android.com/tools"
  173.     android:layout_width="match_parent"
  174.     android:layout_height="match_parent"
  175.     tools:context=".MainActivity"
  176.     android:orientation="vertical"
  177.     android:gravity="center">
  178.    <ImageView
  179.        android:id="@+id/imageView"
  180.        android:layout_height="match_parent"
  181.        android:layout_width="match_parent"
  182.        android:scaleType="centerCrop"
  183.        android:visibility="gone" />
  184.    <Button
  185.        android:id="@+id/btn_back"
  186.        android:layout_width="250dp"
  187.        android:layout_height="wrap_content"
  188.        android:text="加载图片"
  189.        android:textSize="40sp"/>
  190. </LinearLayout>  }
  191.     }
  192.     println("main-end")
  193.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  194. }
  195. suspend fun test(tag: String) {
  196.     for (i in 1..2) {
  197. <?xml version="1.0" encoding="utf-8"?>
  198. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  199.     xmlns:tools="http://schemas.android.com/tools"
  200.     android:layout_width="match_parent"
  201.     android:layout_height="match_parent"
  202.     tools:context=".MainActivity"
  203.     android:orientation="vertical"
  204.     android:gravity="center">
  205.    <ImageView
  206.        android:id="@+id/imageView"
  207.        android:layout_height="match_parent"
  208.        android:layout_width="match_parent"
  209.        android:scaleType="centerCrop"
  210.        android:visibility="gone" />
  211.    <Button
  212.        android:id="@+id/btn_back"
  213.        android:layout_width="250dp"
  214.        android:layout_height="wrap_content"
  215.        android:text="加载图片"
  216.        android:textSize="40sp"/>
  217. </LinearLayout>  println("$tag-$i")
  218. <?xml version="1.0" encoding="utf-8"?>
  219. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  220.     xmlns:tools="http://schemas.android.com/tools"
  221.     android:layout_width="match_parent"
  222.     android:layout_height="match_parent"
  223.     tools:context=".MainActivity"
  224.     android:orientation="vertical"
  225.     android:gravity="center">
  226.    <ImageView
  227.        android:id="@+id/imageView"
  228.        android:layout_height="match_parent"
  229.        android:layout_width="match_parent"
  230.        android:scaleType="centerCrop"
  231.        android:visibility="gone" />
  232.    <Button
  233.        android:id="@+id/btn_back"
  234.        android:layout_width="250dp"
  235.        android:layout_height="wrap_content"
  236.        android:text="加载图片"
  237.        android:textSize="40sp"/>
  238. </LinearLayout>  delay(100)
  239.     }
  240. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. CoroutineScope-A-1
  4. CoroutineScope-A-2
  5. CoroutineScope-B-1
  6. CoroutineScope-C-1
  7. CoroutineScope-B-2
  8. CoroutineScope-C-2
复制代码
​    说明:结果表明 main 与 CoroutineScope-A 并行,CoroutineScope-A 运行结束后,又启动了 GlobalScope-B、CoroutineScope-C 两个子协程,它们又并行。
4.2 协程启动方式应用

4.2.1 launch
  1. fun main() {
  2.     println("main-start")
  3.     MainScope().launch(Dispatchers.Default, CoroutineStart.DEFAULT) {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  test("MainScope")
  25.     }
  26.     println("main-end")
  27.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  28. }
  29. suspend fun test(tag: String) {
  30.     for (i in 1..2) {
  31. <?xml version="1.0" encoding="utf-8"?>
  32. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  33.     xmlns:tools="http://schemas.android.com/tools"
  34.     android:layout_width="match_parent"
  35.     android:layout_height="match_parent"
  36.     tools:context=".MainActivity"
  37.     android:orientation="vertical"
  38.     android:gravity="center">
  39.    <ImageView
  40.        android:id="@+id/imageView"
  41.        android:layout_height="match_parent"
  42.        android:layout_width="match_parent"
  43.        android:scaleType="centerCrop"
  44.        android:visibility="gone" />
  45.    <Button
  46.        android:id="@+id/btn_back"
  47.        android:layout_width="250dp"
  48.        android:layout_height="wrap_content"
  49.        android:text="加载图片"
  50.        android:textSize="40sp"/>
  51. </LinearLayout>  println("$tag-$i")
  52. <?xml version="1.0" encoding="utf-8"?>
  53. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  54.     xmlns:tools="http://schemas.android.com/tools"
  55.     android:layout_width="match_parent"
  56.     android:layout_height="match_parent"
  57.     tools:context=".MainActivity"
  58.     android:orientation="vertical"
  59.     android:gravity="center">
  60.    <ImageView
  61.        android:id="@+id/imageView"
  62.        android:layout_height="match_parent"
  63.        android:layout_width="match_parent"
  64.        android:scaleType="centerCrop"
  65.        android:visibility="gone" />
  66.    <Button
  67.        android:id="@+id/btn_back"
  68.        android:layout_width="250dp"
  69.        android:layout_height="wrap_content"
  70.        android:text="加载图片"
  71.        android:textSize="40sp"/>
  72. </LinearLayout>  delay(100)
  73.     }
  74. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. MainScope-1
  4. MainScope-2
复制代码
4.2.2 async
  1. fun main() {
  2.     println("main-start")
  3.     MainScope().launch(Dispatchers.Default) {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  var deferred = async { // 启动子协程
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  46. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  47.     xmlns:tools="http://schemas.android.com/tools"
  48.     android:layout_width="match_parent"
  49.     android:layout_height="match_parent"
  50.     tools:context=".MainActivity"
  51.     android:orientation="vertical"
  52.     android:gravity="center">
  53.    <ImageView
  54.        android:id="@+id/imageView"
  55.        android:layout_height="match_parent"
  56.        android:layout_width="match_parent"
  57.        android:scaleType="centerCrop"
  58.        android:visibility="gone" />
  59.    <Button
  60.        android:id="@+id/btn_back"
  61.        android:layout_width="250dp"
  62.        android:layout_height="wrap_content"
  63.        android:text="加载图片"
  64.        android:textSize="40sp"/>
  65. </LinearLayout>test("MainScope")
  66. <?xml version="1.0" encoding="utf-8"?>
  67. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  68.     xmlns:tools="http://schemas.android.com/tools"
  69.     android:layout_width="match_parent"
  70.     android:layout_height="match_parent"
  71.     tools:context=".MainActivity"
  72.     android:orientation="vertical"
  73.     android:gravity="center">
  74.    <ImageView
  75.        android:id="@+id/imageView"
  76.        android:layout_height="match_parent"
  77.        android:layout_width="match_parent"
  78.        android:scaleType="centerCrop"
  79.        android:visibility="gone" />
  80.    <Button
  81.        android:id="@+id/btn_back"
  82.        android:layout_width="250dp"
  83.        android:layout_height="wrap_content"
  84.        android:text="加载图片"
  85.        android:textSize="40sp"/>
  86. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  87. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  88.     xmlns:tools="http://schemas.android.com/tools"
  89.     android:layout_width="match_parent"
  90.     android:layout_height="match_parent"
  91.     tools:context=".MainActivity"
  92.     android:orientation="vertical"
  93.     android:gravity="center">
  94.    <ImageView
  95.        android:id="@+id/imageView"
  96.        android:layout_height="match_parent"
  97.        android:layout_width="match_parent"
  98.        android:scaleType="centerCrop"
  99.        android:visibility="gone" />
  100.    <Button
  101.        android:id="@+id/btn_back"
  102.        android:layout_width="250dp"
  103.        android:layout_height="wrap_content"
  104.        android:text="加载图片"
  105.        android:textSize="40sp"/>
  106. </LinearLayout>"async return value"
  107. <?xml version="1.0" encoding="utf-8"?>
  108. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  109.     xmlns:tools="http://schemas.android.com/tools"
  110.     android:layout_width="match_parent"
  111.     android:layout_height="match_parent"
  112.     tools:context=".MainActivity"
  113.     android:orientation="vertical"
  114.     android:gravity="center">
  115.    <ImageView
  116.        android:id="@+id/imageView"
  117.        android:layout_height="match_parent"
  118.        android:layout_width="match_parent"
  119.        android:scaleType="centerCrop"
  120.        android:visibility="gone" />
  121.    <Button
  122.        android:id="@+id/btn_back"
  123.        android:layout_width="250dp"
  124.        android:layout_height="wrap_content"
  125.        android:text="加载图片"
  126.        android:textSize="40sp"/>
  127. </LinearLayout>  }
  128. <?xml version="1.0" encoding="utf-8"?>
  129. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  130.     xmlns:tools="http://schemas.android.com/tools"
  131.     android:layout_width="match_parent"
  132.     android:layout_height="match_parent"
  133.     tools:context=".MainActivity"
  134.     android:orientation="vertical"
  135.     android:gravity="center">
  136.    <ImageView
  137.        android:id="@+id/imageView"
  138.        android:layout_height="match_parent"
  139.        android:layout_width="match_parent"
  140.        android:scaleType="centerCrop"
  141.        android:visibility="gone" />
  142.    <Button
  143.        android:id="@+id/btn_back"
  144.        android:layout_width="250dp"
  145.        android:layout_height="wrap_content"
  146.        android:text="加载图片"
  147.        android:textSize="40sp"/>
  148. </LinearLayout>  println("MainScope-xxx")
  149. <?xml version="1.0" encoding="utf-8"?>
  150. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  151.     xmlns:tools="http://schemas.android.com/tools"
  152.     android:layout_width="match_parent"
  153.     android:layout_height="match_parent"
  154.     tools:context=".MainActivity"
  155.     android:orientation="vertical"
  156.     android:gravity="center">
  157.    <ImageView
  158.        android:id="@+id/imageView"
  159.        android:layout_height="match_parent"
  160.        android:layout_width="match_parent"
  161.        android:scaleType="centerCrop"
  162.        android:visibility="gone" />
  163.    <Button
  164.        android:id="@+id/btn_back"
  165.        android:layout_width="250dp"
  166.        android:layout_height="wrap_content"
  167.        android:text="加载图片"
  168.        android:textSize="40sp"/>
  169. </LinearLayout>  var res = deferred.await() // 获取子协程的返回值, 此处会挂起当前协程, 直到子协程执行完成
  170. <?xml version="1.0" encoding="utf-8"?>
  171. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  172.     xmlns:tools="http://schemas.android.com/tools"
  173.     android:layout_width="match_parent"
  174.     android:layout_height="match_parent"
  175.     tools:context=".MainActivity"
  176.     android:orientation="vertical"
  177.     android:gravity="center">
  178.    <ImageView
  179.        android:id="@+id/imageView"
  180.        android:layout_height="match_parent"
  181.        android:layout_width="match_parent"
  182.        android:scaleType="centerCrop"
  183.        android:visibility="gone" />
  184.    <Button
  185.        android:id="@+id/btn_back"
  186.        android:layout_width="250dp"
  187.        android:layout_height="wrap_content"
  188.        android:text="加载图片"
  189.        android:textSize="40sp"/>
  190. </LinearLayout>  println(res)
  191.     }
  192.     println("main-end")
  193.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  194. }
  195. suspend fun test(tag: String) {
  196.     for (i in 1..2) {
  197. <?xml version="1.0" encoding="utf-8"?>
  198. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  199.     xmlns:tools="http://schemas.android.com/tools"
  200.     android:layout_width="match_parent"
  201.     android:layout_height="match_parent"
  202.     tools:context=".MainActivity"
  203.     android:orientation="vertical"
  204.     android:gravity="center">
  205.    <ImageView
  206.        android:id="@+id/imageView"
  207.        android:layout_height="match_parent"
  208.        android:layout_width="match_parent"
  209.        android:scaleType="centerCrop"
  210.        android:visibility="gone" />
  211.    <Button
  212.        android:id="@+id/btn_back"
  213.        android:layout_width="250dp"
  214.        android:layout_height="wrap_content"
  215.        android:text="加载图片"
  216.        android:textSize="40sp"/>
  217. </LinearLayout>  println("$tag-$i")
  218. <?xml version="1.0" encoding="utf-8"?>
  219. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  220.     xmlns:tools="http://schemas.android.com/tools"
  221.     android:layout_width="match_parent"
  222.     android:layout_height="match_parent"
  223.     tools:context=".MainActivity"
  224.     android:orientation="vertical"
  225.     android:gravity="center">
  226.    <ImageView
  227.        android:id="@+id/imageView"
  228.        android:layout_height="match_parent"
  229.        android:layout_width="match_parent"
  230.        android:scaleType="centerCrop"
  231.        android:visibility="gone" />
  232.    <Button
  233.        android:id="@+id/btn_back"
  234.        android:layout_width="250dp"
  235.        android:layout_height="wrap_content"
  236.        android:text="加载图片"
  237.        android:textSize="40sp"/>
  238. </LinearLayout>  delay(100)
  239.     }
  240. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. MainScope-xxx
  4. MainScope-1
  5. MainScope-2
  6. async return value
复制代码
​    说明:结果表明 deferred.await() 会挂起当前协程(MainScope),直到子协程(async)执行完成。
4.2.3 runBlocking
  1. fun main() {
  2.     println("main-start")
  3.     runBlocking {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  var deferred = async { // 启动子协程
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  46. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  47.     xmlns:tools="http://schemas.android.com/tools"
  48.     android:layout_width="match_parent"
  49.     android:layout_height="match_parent"
  50.     tools:context=".MainActivity"
  51.     android:orientation="vertical"
  52.     android:gravity="center">
  53.    <ImageView
  54.        android:id="@+id/imageView"
  55.        android:layout_height="match_parent"
  56.        android:layout_width="match_parent"
  57.        android:scaleType="centerCrop"
  58.        android:visibility="gone" />
  59.    <Button
  60.        android:id="@+id/btn_back"
  61.        android:layout_width="250dp"
  62.        android:layout_height="wrap_content"
  63.        android:text="加载图片"
  64.        android:textSize="40sp"/>
  65. </LinearLayout>test("runBlocking")
  66. <?xml version="1.0" encoding="utf-8"?>
  67. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  68.     xmlns:tools="http://schemas.android.com/tools"
  69.     android:layout_width="match_parent"
  70.     android:layout_height="match_parent"
  71.     tools:context=".MainActivity"
  72.     android:orientation="vertical"
  73.     android:gravity="center">
  74.    <ImageView
  75.        android:id="@+id/imageView"
  76.        android:layout_height="match_parent"
  77.        android:layout_width="match_parent"
  78.        android:scaleType="centerCrop"
  79.        android:visibility="gone" />
  80.    <Button
  81.        android:id="@+id/btn_back"
  82.        android:layout_width="250dp"
  83.        android:layout_height="wrap_content"
  84.        android:text="加载图片"
  85.        android:textSize="40sp"/>
  86. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  87. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  88.     xmlns:tools="http://schemas.android.com/tools"
  89.     android:layout_width="match_parent"
  90.     android:layout_height="match_parent"
  91.     tools:context=".MainActivity"
  92.     android:orientation="vertical"
  93.     android:gravity="center">
  94.    <ImageView
  95.        android:id="@+id/imageView"
  96.        android:layout_height="match_parent"
  97.        android:layout_width="match_parent"
  98.        android:scaleType="centerCrop"
  99.        android:visibility="gone" />
  100.    <Button
  101.        android:id="@+id/btn_back"
  102.        android:layout_width="250dp"
  103.        android:layout_height="wrap_content"
  104.        android:text="加载图片"
  105.        android:textSize="40sp"/>
  106. </LinearLayout>"async return value"
  107. <?xml version="1.0" encoding="utf-8"?>
  108. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  109.     xmlns:tools="http://schemas.android.com/tools"
  110.     android:layout_width="match_parent"
  111.     android:layout_height="match_parent"
  112.     tools:context=".MainActivity"
  113.     android:orientation="vertical"
  114.     android:gravity="center">
  115.    <ImageView
  116.        android:id="@+id/imageView"
  117.        android:layout_height="match_parent"
  118.        android:layout_width="match_parent"
  119.        android:scaleType="centerCrop"
  120.        android:visibility="gone" />
  121.    <Button
  122.        android:id="@+id/btn_back"
  123.        android:layout_width="250dp"
  124.        android:layout_height="wrap_content"
  125.        android:text="加载图片"
  126.        android:textSize="40sp"/>
  127. </LinearLayout>  }
  128. <?xml version="1.0" encoding="utf-8"?>
  129. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  130.     xmlns:tools="http://schemas.android.com/tools"
  131.     android:layout_width="match_parent"
  132.     android:layout_height="match_parent"
  133.     tools:context=".MainActivity"
  134.     android:orientation="vertical"
  135.     android:gravity="center">
  136.    <ImageView
  137.        android:id="@+id/imageView"
  138.        android:layout_height="match_parent"
  139.        android:layout_width="match_parent"
  140.        android:scaleType="centerCrop"
  141.        android:visibility="gone" />
  142.    <Button
  143.        android:id="@+id/btn_back"
  144.        android:layout_width="250dp"
  145.        android:layout_height="wrap_content"
  146.        android:text="加载图片"
  147.        android:textSize="40sp"/>
  148. </LinearLayout>  launch { // 启动子协程
  149. <?xml version="1.0" encoding="utf-8"?>
  150. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  151.     xmlns:tools="http://schemas.android.com/tools"
  152.     android:layout_width="match_parent"
  153.     android:layout_height="match_parent"
  154.     tools:context=".MainActivity"
  155.     android:orientation="vertical"
  156.     android:gravity="center">
  157.    <ImageView
  158.        android:id="@+id/imageView"
  159.        android:layout_height="match_parent"
  160.        android:layout_width="match_parent"
  161.        android:scaleType="centerCrop"
  162.        android:visibility="gone" />
  163.    <Button
  164.        android:id="@+id/btn_back"
  165.        android:layout_width="250dp"
  166.        android:layout_height="wrap_content"
  167.        android:text="加载图片"
  168.        android:textSize="40sp"/>
  169. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  170. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  171.     xmlns:tools="http://schemas.android.com/tools"
  172.     android:layout_width="match_parent"
  173.     android:layout_height="match_parent"
  174.     tools:context=".MainActivity"
  175.     android:orientation="vertical"
  176.     android:gravity="center">
  177.    <ImageView
  178.        android:id="@+id/imageView"
  179.        android:layout_height="match_parent"
  180.        android:layout_width="match_parent"
  181.        android:scaleType="centerCrop"
  182.        android:visibility="gone" />
  183.    <Button
  184.        android:id="@+id/btn_back"
  185.        android:layout_width="250dp"
  186.        android:layout_height="wrap_content"
  187.        android:text="加载图片"
  188.        android:textSize="40sp"/>
  189. </LinearLayout>var res = deferred.await() // 获取子协程的返回值, 此处会挂起当前协程, 直到子协程执行完成
  190. <?xml version="1.0" encoding="utf-8"?>
  191. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  192.     xmlns:tools="http://schemas.android.com/tools"
  193.     android:layout_width="match_parent"
  194.     android:layout_height="match_parent"
  195.     tools:context=".MainActivity"
  196.     android:orientation="vertical"
  197.     android:gravity="center">
  198.    <ImageView
  199.        android:id="@+id/imageView"
  200.        android:layout_height="match_parent"
  201.        android:layout_width="match_parent"
  202.        android:scaleType="centerCrop"
  203.        android:visibility="gone" />
  204.    <Button
  205.        android:id="@+id/btn_back"
  206.        android:layout_width="250dp"
  207.        android:layout_height="wrap_content"
  208.        android:text="加载图片"
  209.        android:textSize="40sp"/>
  210. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  211. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  212.     xmlns:tools="http://schemas.android.com/tools"
  213.     android:layout_width="match_parent"
  214.     android:layout_height="match_parent"
  215.     tools:context=".MainActivity"
  216.     android:orientation="vertical"
  217.     android:gravity="center">
  218.    <ImageView
  219.        android:id="@+id/imageView"
  220.        android:layout_height="match_parent"
  221.        android:layout_width="match_parent"
  222.        android:scaleType="centerCrop"
  223.        android:visibility="gone" />
  224.    <Button
  225.        android:id="@+id/btn_back"
  226.        android:layout_width="250dp"
  227.        android:layout_height="wrap_content"
  228.        android:text="加载图片"
  229.        android:textSize="40sp"/>
  230. </LinearLayout>println(res)
  231. <?xml version="1.0" encoding="utf-8"?>
  232. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  233.     xmlns:tools="http://schemas.android.com/tools"
  234.     android:layout_width="match_parent"
  235.     android:layout_height="match_parent"
  236.     tools:context=".MainActivity"
  237.     android:orientation="vertical"
  238.     android:gravity="center">
  239.    <ImageView
  240.        android:id="@+id/imageView"
  241.        android:layout_height="match_parent"
  242.        android:layout_width="match_parent"
  243.        android:scaleType="centerCrop"
  244.        android:visibility="gone" />
  245.    <Button
  246.        android:id="@+id/btn_back"
  247.        android:layout_width="250dp"
  248.        android:layout_height="wrap_content"
  249.        android:text="加载图片"
  250.        android:textSize="40sp"/>
  251. </LinearLayout>  }
  252. <?xml version="1.0" encoding="utf-8"?>
  253. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  254.     xmlns:tools="http://schemas.android.com/tools"
  255.     android:layout_width="match_parent"
  256.     android:layout_height="match_parent"
  257.     tools:context=".MainActivity"
  258.     android:orientation="vertical"
  259.     android:gravity="center">
  260.    <ImageView
  261.        android:id="@+id/imageView"
  262.        android:layout_height="match_parent"
  263.        android:layout_width="match_parent"
  264.        android:scaleType="centerCrop"
  265.        android:visibility="gone" />
  266.    <Button
  267.        android:id="@+id/btn_back"
  268.        android:layout_width="250dp"
  269.        android:layout_height="wrap_content"
  270.        android:text="加载图片"
  271.        android:textSize="40sp"/>
  272. </LinearLayout>  println("runBlocking-xxx")
  273.     }
  274.     println("main-end")
  275.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  276. }
  277. suspend fun test(tag: String) {
  278.     for (i in 1..2) {
  279. <?xml version="1.0" encoding="utf-8"?>
  280. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  281.     xmlns:tools="http://schemas.android.com/tools"
  282.     android:layout_width="match_parent"
  283.     android:layout_height="match_parent"
  284.     tools:context=".MainActivity"
  285.     android:orientation="vertical"
  286.     android:gravity="center">
  287.    <ImageView
  288.        android:id="@+id/imageView"
  289.        android:layout_height="match_parent"
  290.        android:layout_width="match_parent"
  291.        android:scaleType="centerCrop"
  292.        android:visibility="gone" />
  293.    <Button
  294.        android:id="@+id/btn_back"
  295.        android:layout_width="250dp"
  296.        android:layout_height="wrap_content"
  297.        android:text="加载图片"
  298.        android:textSize="40sp"/>
  299. </LinearLayout>  println("$tag-$i")
  300. <?xml version="1.0" encoding="utf-8"?>
  301. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  302.     xmlns:tools="http://schemas.android.com/tools"
  303.     android:layout_width="match_parent"
  304.     android:layout_height="match_parent"
  305.     tools:context=".MainActivity"
  306.     android:orientation="vertical"
  307.     android:gravity="center">
  308.    <ImageView
  309.        android:id="@+id/imageView"
  310.        android:layout_height="match_parent"
  311.        android:layout_width="match_parent"
  312.        android:scaleType="centerCrop"
  313.        android:visibility="gone" />
  314.    <Button
  315.        android:id="@+id/btn_back"
  316.        android:layout_width="250dp"
  317.        android:layout_height="wrap_content"
  318.        android:text="加载图片"
  319.        android:textSize="40sp"/>
  320. </LinearLayout>  delay(100)
  321.     }
  322. }
复制代码
​    打印如下。
  1. main-start
  2. runBlocking-xxx
  3. runBlocking-1
  4. runBlocking-2
  5. async return value
  6. main-end
复制代码
​    说明:结果表明 runBlocking 启动了一个新的协程(runBlocking),并阻塞了当前线程(main),直到协程执行完成;deferred.await() 会挂起当前子协程(async),直到子协程(launch)执行完成。
4.2.4 withContext

​    1)不使用 withContext 返回值
  1. @OptIn(ExperimentalStdlibApi::class)
  2. fun main() {
  3.     println("main-start")
  4.     runBlocking(Dispatchers.IO) {
  5. <?xml version="1.0" encoding="utf-8"?>
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  7.     xmlns:tools="http://schemas.android.com/tools"
  8.     android:layout_width="match_parent"
  9.     android:layout_height="match_parent"
  10.     tools:context=".MainActivity"
  11.     android:orientation="vertical"
  12.     android:gravity="center">
  13.    <ImageView
  14.        android:id="@+id/imageView"
  15.        android:layout_height="match_parent"
  16.        android:layout_width="match_parent"
  17.        android:scaleType="centerCrop"
  18.        android:visibility="gone" />
  19.    <Button
  20.        android:id="@+id/btn_back"
  21.        android:layout_width="250dp"
  22.        android:layout_height="wrap_content"
  23.        android:text="加载图片"
  24.        android:textSize="40sp"/>
  25. </LinearLayout>  println("context1=${coroutineContext[CoroutineDispatcher]}")
  26. <?xml version="1.0" encoding="utf-8"?>
  27. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  28.     xmlns:tools="http://schemas.android.com/tools"
  29.     android:layout_width="match_parent"
  30.     android:layout_height="match_parent"
  31.     tools:context=".MainActivity"
  32.     android:orientation="vertical"
  33.     android:gravity="center">
  34.    <ImageView
  35.        android:id="@+id/imageView"
  36.        android:layout_height="match_parent"
  37.        android:layout_width="match_parent"
  38.        android:scaleType="centerCrop"
  39.        android:visibility="gone" />
  40.    <Button
  41.        android:id="@+id/btn_back"
  42.        android:layout_width="250dp"
  43.        android:layout_height="wrap_content"
  44.        android:text="加载图片"
  45.        android:textSize="40sp"/>
  46. </LinearLayout>  withContext(Dispatchers.Default) { // 启动子协程, 并挂起当前协程
  47. <?xml version="1.0" encoding="utf-8"?>
  48. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  49.     xmlns:tools="http://schemas.android.com/tools"
  50.     android:layout_width="match_parent"
  51.     android:layout_height="match_parent"
  52.     tools:context=".MainActivity"
  53.     android:orientation="vertical"
  54.     android:gravity="center">
  55.    <ImageView
  56.        android:id="@+id/imageView"
  57.        android:layout_height="match_parent"
  58.        android:layout_width="match_parent"
  59.        android:scaleType="centerCrop"
  60.        android:visibility="gone" />
  61.    <Button
  62.        android:id="@+id/btn_back"
  63.        android:layout_width="250dp"
  64.        android:layout_height="wrap_content"
  65.        android:text="加载图片"
  66.        android:textSize="40sp"/>
  67. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  68. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  69.     xmlns:tools="http://schemas.android.com/tools"
  70.     android:layout_width="match_parent"
  71.     android:layout_height="match_parent"
  72.     tools:context=".MainActivity"
  73.     android:orientation="vertical"
  74.     android:gravity="center">
  75.    <ImageView
  76.        android:id="@+id/imageView"
  77.        android:layout_height="match_parent"
  78.        android:layout_width="match_parent"
  79.        android:scaleType="centerCrop"
  80.        android:visibility="gone" />
  81.    <Button
  82.        android:id="@+id/btn_back"
  83.        android:layout_width="250dp"
  84.        android:layout_height="wrap_content"
  85.        android:text="加载图片"
  86.        android:textSize="40sp"/>
  87. </LinearLayout>println("context2=${coroutineContext[CoroutineDispatcher]}")
  88. <?xml version="1.0" encoding="utf-8"?>
  89. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  90.     xmlns:tools="http://schemas.android.com/tools"
  91.     android:layout_width="match_parent"
  92.     android:layout_height="match_parent"
  93.     tools:context=".MainActivity"
  94.     android:orientation="vertical"
  95.     android:gravity="center">
  96.    <ImageView
  97.        android:id="@+id/imageView"
  98.        android:layout_height="match_parent"
  99.        android:layout_width="match_parent"
  100.        android:scaleType="centerCrop"
  101.        android:visibility="gone" />
  102.    <Button
  103.        android:id="@+id/btn_back"
  104.        android:layout_width="250dp"
  105.        android:layout_height="wrap_content"
  106.        android:text="加载图片"
  107.        android:textSize="40sp"/>
  108. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  109. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  110.     xmlns:tools="http://schemas.android.com/tools"
  111.     android:layout_width="match_parent"
  112.     android:layout_height="match_parent"
  113.     tools:context=".MainActivity"
  114.     android:orientation="vertical"
  115.     android:gravity="center">
  116.    <ImageView
  117.        android:id="@+id/imageView"
  118.        android:layout_height="match_parent"
  119.        android:layout_width="match_parent"
  120.        android:scaleType="centerCrop"
  121.        android:visibility="gone" />
  122.    <Button
  123.        android:id="@+id/btn_back"
  124.        android:layout_width="250dp"
  125.        android:layout_height="wrap_content"
  126.        android:text="加载图片"
  127.        android:textSize="40sp"/>
  128. </LinearLayout>test("withContext")
  129. <?xml version="1.0" encoding="utf-8"?>
  130. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  131.     xmlns:tools="http://schemas.android.com/tools"
  132.     android:layout_width="match_parent"
  133.     android:layout_height="match_parent"
  134.     tools:context=".MainActivity"
  135.     android:orientation="vertical"
  136.     android:gravity="center">
  137.    <ImageView
  138.        android:id="@+id/imageView"
  139.        android:layout_height="match_parent"
  140.        android:layout_width="match_parent"
  141.        android:scaleType="centerCrop"
  142.        android:visibility="gone" />
  143.    <Button
  144.        android:id="@+id/btn_back"
  145.        android:layout_width="250dp"
  146.        android:layout_height="wrap_content"
  147.        android:text="加载图片"
  148.        android:textSize="40sp"/>
  149. </LinearLayout>  }
  150. <?xml version="1.0" encoding="utf-8"?>
  151. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  152.     xmlns:tools="http://schemas.android.com/tools"
  153.     android:layout_width="match_parent"
  154.     android:layout_height="match_parent"
  155.     tools:context=".MainActivity"
  156.     android:orientation="vertical"
  157.     android:gravity="center">
  158.    <ImageView
  159.        android:id="@+id/imageView"
  160.        android:layout_height="match_parent"
  161.        android:layout_width="match_parent"
  162.        android:scaleType="centerCrop"
  163.        android:visibility="gone" />
  164.    <Button
  165.        android:id="@+id/btn_back"
  166.        android:layout_width="250dp"
  167.        android:layout_height="wrap_content"
  168.        android:text="加载图片"
  169.        android:textSize="40sp"/>
  170. </LinearLayout>  println("runBlocking-xxx")
  171.     }
  172.     println("main-end")
  173.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  174. }
  175. suspend fun test(tag: String) {
  176.     for (i in 1..2) {
  177. <?xml version="1.0" encoding="utf-8"?>
  178. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  179.     xmlns:tools="http://schemas.android.com/tools"
  180.     android:layout_width="match_parent"
  181.     android:layout_height="match_parent"
  182.     tools:context=".MainActivity"
  183.     android:orientation="vertical"
  184.     android:gravity="center">
  185.    <ImageView
  186.        android:id="@+id/imageView"
  187.        android:layout_height="match_parent"
  188.        android:layout_width="match_parent"
  189.        android:scaleType="centerCrop"
  190.        android:visibility="gone" />
  191.    <Button
  192.        android:id="@+id/btn_back"
  193.        android:layout_width="250dp"
  194.        android:layout_height="wrap_content"
  195.        android:text="加载图片"
  196.        android:textSize="40sp"/>
  197. </LinearLayout>  println("$tag-$i")
  198. <?xml version="1.0" encoding="utf-8"?>
  199. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  200.     xmlns:tools="http://schemas.android.com/tools"
  201.     android:layout_width="match_parent"
  202.     android:layout_height="match_parent"
  203.     tools:context=".MainActivity"
  204.     android:orientation="vertical"
  205.     android:gravity="center">
  206.    <ImageView
  207.        android:id="@+id/imageView"
  208.        android:layout_height="match_parent"
  209.        android:layout_width="match_parent"
  210.        android:scaleType="centerCrop"
  211.        android:visibility="gone" />
  212.    <Button
  213.        android:id="@+id/btn_back"
  214.        android:layout_width="250dp"
  215.        android:layout_height="wrap_content"
  216.        android:text="加载图片"
  217.        android:textSize="40sp"/>
  218. </LinearLayout>  delay(100)
  219.     }
  220. }
复制代码
​    打印如下。
  1. main-start
  2. context1=Dispatchers.IO
  3. context2=Dispatchers.Default
  4. withContext-1
  5. withContext-2
  6. runBlocking-xxx
  7. main-end
复制代码
​    说明:结果表明 withContext 创建了子协程,并挂起了 runBlocking 协程,直到 withContext 协程执行完毕才恢复执行。
​    2)使用 withContext 返回值
  1. @OptIn(ExperimentalStdlibApi::class)
  2. fun main() {
  3.     println("main-start")
  4.     runBlocking(Dispatchers.IO) {
  5. <?xml version="1.0" encoding="utf-8"?>
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  7.     xmlns:tools="http://schemas.android.com/tools"
  8.     android:layout_width="match_parent"
  9.     android:layout_height="match_parent"
  10.     tools:context=".MainActivity"
  11.     android:orientation="vertical"
  12.     android:gravity="center">
  13.    <ImageView
  14.        android:id="@+id/imageView"
  15.        android:layout_height="match_parent"
  16.        android:layout_width="match_parent"
  17.        android:scaleType="centerCrop"
  18.        android:visibility="gone" />
  19.    <Button
  20.        android:id="@+id/btn_back"
  21.        android:layout_width="250dp"
  22.        android:layout_height="wrap_content"
  23.        android:text="加载图片"
  24.        android:textSize="40sp"/>
  25. </LinearLayout>  println("context1=${coroutineContext[CoroutineDispatcher]}")
  26. <?xml version="1.0" encoding="utf-8"?>
  27. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  28.     xmlns:tools="http://schemas.android.com/tools"
  29.     android:layout_width="match_parent"
  30.     android:layout_height="match_parent"
  31.     tools:context=".MainActivity"
  32.     android:orientation="vertical"
  33.     android:gravity="center">
  34.    <ImageView
  35.        android:id="@+id/imageView"
  36.        android:layout_height="match_parent"
  37.        android:layout_width="match_parent"
  38.        android:scaleType="centerCrop"
  39.        android:visibility="gone" />
  40.    <Button
  41.        android:id="@+id/btn_back"
  42.        android:layout_width="250dp"
  43.        android:layout_height="wrap_content"
  44.        android:text="加载图片"
  45.        android:textSize="40sp"/>
  46. </LinearLayout>  var res = withContext(Dispatchers.Default) { // 启动子协程, 并挂起当前协程
  47. <?xml version="1.0" encoding="utf-8"?>
  48. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  49.     xmlns:tools="http://schemas.android.com/tools"
  50.     android:layout_width="match_parent"
  51.     android:layout_height="match_parent"
  52.     tools:context=".MainActivity"
  53.     android:orientation="vertical"
  54.     android:gravity="center">
  55.    <ImageView
  56.        android:id="@+id/imageView"
  57.        android:layout_height="match_parent"
  58.        android:layout_width="match_parent"
  59.        android:scaleType="centerCrop"
  60.        android:visibility="gone" />
  61.    <Button
  62.        android:id="@+id/btn_back"
  63.        android:layout_width="250dp"
  64.        android:layout_height="wrap_content"
  65.        android:text="加载图片"
  66.        android:textSize="40sp"/>
  67. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  68. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  69.     xmlns:tools="http://schemas.android.com/tools"
  70.     android:layout_width="match_parent"
  71.     android:layout_height="match_parent"
  72.     tools:context=".MainActivity"
  73.     android:orientation="vertical"
  74.     android:gravity="center">
  75.    <ImageView
  76.        android:id="@+id/imageView"
  77.        android:layout_height="match_parent"
  78.        android:layout_width="match_parent"
  79.        android:scaleType="centerCrop"
  80.        android:visibility="gone" />
  81.    <Button
  82.        android:id="@+id/btn_back"
  83.        android:layout_width="250dp"
  84.        android:layout_height="wrap_content"
  85.        android:text="加载图片"
  86.        android:textSize="40sp"/>
  87. </LinearLayout>println("context2=${coroutineContext[CoroutineDispatcher]}")
  88. <?xml version="1.0" encoding="utf-8"?>
  89. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  90.     xmlns:tools="http://schemas.android.com/tools"
  91.     android:layout_width="match_parent"
  92.     android:layout_height="match_parent"
  93.     tools:context=".MainActivity"
  94.     android:orientation="vertical"
  95.     android:gravity="center">
  96.    <ImageView
  97.        android:id="@+id/imageView"
  98.        android:layout_height="match_parent"
  99.        android:layout_width="match_parent"
  100.        android:scaleType="centerCrop"
  101.        android:visibility="gone" />
  102.    <Button
  103.        android:id="@+id/btn_back"
  104.        android:layout_width="250dp"
  105.        android:layout_height="wrap_content"
  106.        android:text="加载图片"
  107.        android:textSize="40sp"/>
  108. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  109. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  110.     xmlns:tools="http://schemas.android.com/tools"
  111.     android:layout_width="match_parent"
  112.     android:layout_height="match_parent"
  113.     tools:context=".MainActivity"
  114.     android:orientation="vertical"
  115.     android:gravity="center">
  116.    <ImageView
  117.        android:id="@+id/imageView"
  118.        android:layout_height="match_parent"
  119.        android:layout_width="match_parent"
  120.        android:scaleType="centerCrop"
  121.        android:visibility="gone" />
  122.    <Button
  123.        android:id="@+id/btn_back"
  124.        android:layout_width="250dp"
  125.        android:layout_height="wrap_content"
  126.        android:text="加载图片"
  127.        android:textSize="40sp"/>
  128. </LinearLayout>"withContext return value"
  129. <?xml version="1.0" encoding="utf-8"?>
  130. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  131.     xmlns:tools="http://schemas.android.com/tools"
  132.     android:layout_width="match_parent"
  133.     android:layout_height="match_parent"
  134.     tools:context=".MainActivity"
  135.     android:orientation="vertical"
  136.     android:gravity="center">
  137.    <ImageView
  138.        android:id="@+id/imageView"
  139.        android:layout_height="match_parent"
  140.        android:layout_width="match_parent"
  141.        android:scaleType="centerCrop"
  142.        android:visibility="gone" />
  143.    <Button
  144.        android:id="@+id/btn_back"
  145.        android:layout_width="250dp"
  146.        android:layout_height="wrap_content"
  147.        android:text="加载图片"
  148.        android:textSize="40sp"/>
  149. </LinearLayout>  }
  150. <?xml version="1.0" encoding="utf-8"?>
  151. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  152.     xmlns:tools="http://schemas.android.com/tools"
  153.     android:layout_width="match_parent"
  154.     android:layout_height="match_parent"
  155.     tools:context=".MainActivity"
  156.     android:orientation="vertical"
  157.     android:gravity="center">
  158.    <ImageView
  159.        android:id="@+id/imageView"
  160.        android:layout_height="match_parent"
  161.        android:layout_width="match_parent"
  162.        android:scaleType="centerCrop"
  163.        android:visibility="gone" />
  164.    <Button
  165.        android:id="@+id/btn_back"
  166.        android:layout_width="250dp"
  167.        android:layout_height="wrap_content"
  168.        android:text="加载图片"
  169.        android:textSize="40sp"/>
  170. </LinearLayout>  println("res=$res")
  171.     }
  172.     println("main-end")
  173.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  174. }
复制代码
​    打印如下。
  1. main-start
  2. context1=Dispatchers.IO
  3. context2=Dispatchers.Default
  4. res=withContext return value
  5. main-end
复制代码
4.3 Job 应用

​    Job 状态流程转换如下。(图片来自 Job.kt 源码)

4.3.1 start
  1. fun main() {
  2.     println("main-start")
  3.     var job = MainScope().launch(Dispatchers.Default, CoroutineStart.LAZY) {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  test("MainScope")
  25.     }
  26.     job.start() // 注释该行, job不会执行, test中日志将不会打印
  27.     println("main-end")
  28.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  29. }
  30. suspend fun test(tag: String) {
  31.     for (i in 1..2) {
  32. <?xml version="1.0" encoding="utf-8"?>
  33. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  34.     xmlns:tools="http://schemas.android.com/tools"
  35.     android:layout_width="match_parent"
  36.     android:layout_height="match_parent"
  37.     tools:context=".MainActivity"
  38.     android:orientation="vertical"
  39.     android:gravity="center">
  40.    <ImageView
  41.        android:id="@+id/imageView"
  42.        android:layout_height="match_parent"
  43.        android:layout_width="match_parent"
  44.        android:scaleType="centerCrop"
  45.        android:visibility="gone" />
  46.    <Button
  47.        android:id="@+id/btn_back"
  48.        android:layout_width="250dp"
  49.        android:layout_height="wrap_content"
  50.        android:text="加载图片"
  51.        android:textSize="40sp"/>
  52. </LinearLayout>  println("$tag-$i")
  53. <?xml version="1.0" encoding="utf-8"?>
  54. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  55.     xmlns:tools="http://schemas.android.com/tools"
  56.     android:layout_width="match_parent"
  57.     android:layout_height="match_parent"
  58.     tools:context=".MainActivity"
  59.     android:orientation="vertical"
  60.     android:gravity="center">
  61.    <ImageView
  62.        android:id="@+id/imageView"
  63.        android:layout_height="match_parent"
  64.        android:layout_width="match_parent"
  65.        android:scaleType="centerCrop"
  66.        android:visibility="gone" />
  67.    <Button
  68.        android:id="@+id/btn_back"
  69.        android:layout_width="250dp"
  70.        android:layout_height="wrap_content"
  71.        android:text="加载图片"
  72.        android:textSize="40sp"/>
  73. </LinearLayout>  delay(100)
  74.     }
  75. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. MainScope-1
  4. MainScope-2
复制代码
​    说明:解释掉 job.start(),job 不会执行,test 中日志将不会打印。
4.3.2 cancel
  1. fun main() {
  2.     println("main-start")
  3.     var job = CoroutineScope(Dispatchers.Default).launch {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  test("CoroutineScope")
  25.     }
  26.     job.cancel()
  27.     println("main-end")
  28.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  29. }
  30. suspend fun test(tag: String) {
  31.     for (i in 1..2) {
  32. <?xml version="1.0" encoding="utf-8"?>
  33. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  34.     xmlns:tools="http://schemas.android.com/tools"
  35.     android:layout_width="match_parent"
  36.     android:layout_height="match_parent"
  37.     tools:context=".MainActivity"
  38.     android:orientation="vertical"
  39.     android:gravity="center">
  40.    <ImageView
  41.        android:id="@+id/imageView"
  42.        android:layout_height="match_parent"
  43.        android:layout_width="match_parent"
  44.        android:scaleType="centerCrop"
  45.        android:visibility="gone" />
  46.    <Button
  47.        android:id="@+id/btn_back"
  48.        android:layout_width="250dp"
  49.        android:layout_height="wrap_content"
  50.        android:text="加载图片"
  51.        android:textSize="40sp"/>
  52. </LinearLayout>  println("$tag-$i")
  53. <?xml version="1.0" encoding="utf-8"?>
  54. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  55.     xmlns:tools="http://schemas.android.com/tools"
  56.     android:layout_width="match_parent"
  57.     android:layout_height="match_parent"
  58.     tools:context=".MainActivity"
  59.     android:orientation="vertical"
  60.     android:gravity="center">
  61.    <ImageView
  62.        android:id="@+id/imageView"
  63.        android:layout_height="match_parent"
  64.        android:layout_width="match_parent"
  65.        android:scaleType="centerCrop"
  66.        android:visibility="gone" />
  67.    <Button
  68.        android:id="@+id/btn_back"
  69.        android:layout_width="250dp"
  70.        android:layout_height="wrap_content"
  71.        android:text="加载图片"
  72.        android:textSize="40sp"/>
  73. </LinearLayout>  delay(100)
  74.     }
  75. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. CoroutineScope-1
复制代码
​    说明:CoroutineScope-2 未打印出来,由于协程执行到一半被取消了。
4.3.3 join
  1. fun main() {
  2.     println("main-start")
  3.     var job = CoroutineScope(Dispatchers.Default).launch {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  test("CoroutineScope")
  25.     }
  26.     MainScope().launch(Dispatchers.Default) {
  27. <?xml version="1.0" encoding="utf-8"?>
  28. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  29.     xmlns:tools="http://schemas.android.com/tools"
  30.     android:layout_width="match_parent"
  31.     android:layout_height="match_parent"
  32.     tools:context=".MainActivity"
  33.     android:orientation="vertical"
  34.     android:gravity="center">
  35.    <ImageView
  36.        android:id="@+id/imageView"
  37.        android:layout_height="match_parent"
  38.        android:layout_width="match_parent"
  39.        android:scaleType="centerCrop"
  40.        android:visibility="gone" />
  41.    <Button
  42.        android:id="@+id/btn_back"
  43.        android:layout_width="250dp"
  44.        android:layout_height="wrap_content"
  45.        android:text="加载图片"
  46.        android:textSize="40sp"/>
  47. </LinearLayout>  println("MainScope-xxx")
  48. <?xml version="1.0" encoding="utf-8"?>
  49. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  50.     xmlns:tools="http://schemas.android.com/tools"
  51.     android:layout_width="match_parent"
  52.     android:layout_height="match_parent"
  53.     tools:context=".MainActivity"
  54.     android:orientation="vertical"
  55.     android:gravity="center">
  56.    <ImageView
  57.        android:id="@+id/imageView"
  58.        android:layout_height="match_parent"
  59.        android:layout_width="match_parent"
  60.        android:scaleType="centerCrop"
  61.        android:visibility="gone" />
  62.    <Button
  63.        android:id="@+id/btn_back"
  64.        android:layout_width="250dp"
  65.        android:layout_height="wrap_content"
  66.        android:text="加载图片"
  67.        android:textSize="40sp"/>
  68. </LinearLayout>  job.join() // 挂起当前协程, 直到job执行完成
  69. <?xml version="1.0" encoding="utf-8"?>
  70. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  71.     xmlns:tools="http://schemas.android.com/tools"
  72.     android:layout_width="match_parent"
  73.     android:layout_height="match_parent"
  74.     tools:context=".MainActivity"
  75.     android:orientation="vertical"
  76.     android:gravity="center">
  77.    <ImageView
  78.        android:id="@+id/imageView"
  79.        android:layout_height="match_parent"
  80.        android:layout_width="match_parent"
  81.        android:scaleType="centerCrop"
  82.        android:visibility="gone" />
  83.    <Button
  84.        android:id="@+id/btn_back"
  85.        android:layout_width="250dp"
  86.        android:layout_height="wrap_content"
  87.        android:text="加载图片"
  88.        android:textSize="40sp"/>
  89. </LinearLayout>  test("MainScope")
  90.     }
  91.     println("main-end")
  92.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  93. }
  94. suspend fun test(tag: String) {
  95.     for (i in 1..2) {
  96. <?xml version="1.0" encoding="utf-8"?>
  97. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  98.     xmlns:tools="http://schemas.android.com/tools"
  99.     android:layout_width="match_parent"
  100.     android:layout_height="match_parent"
  101.     tools:context=".MainActivity"
  102.     android:orientation="vertical"
  103.     android:gravity="center">
  104.    <ImageView
  105.        android:id="@+id/imageView"
  106.        android:layout_height="match_parent"
  107.        android:layout_width="match_parent"
  108.        android:scaleType="centerCrop"
  109.        android:visibility="gone" />
  110.    <Button
  111.        android:id="@+id/btn_back"
  112.        android:layout_width="250dp"
  113.        android:layout_height="wrap_content"
  114.        android:text="加载图片"
  115.        android:textSize="40sp"/>
  116. </LinearLayout>  println("$tag-$i")
  117. <?xml version="1.0" encoding="utf-8"?>
  118. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  119.     xmlns:tools="http://schemas.android.com/tools"
  120.     android:layout_width="match_parent"
  121.     android:layout_height="match_parent"
  122.     tools:context=".MainActivity"
  123.     android:orientation="vertical"
  124.     android:gravity="center">
  125.    <ImageView
  126.        android:id="@+id/imageView"
  127.        android:layout_height="match_parent"
  128.        android:layout_width="match_parent"
  129.        android:scaleType="centerCrop"
  130.        android:visibility="gone" />
  131.    <Button
  132.        android:id="@+id/btn_back"
  133.        android:layout_width="250dp"
  134.        android:layout_height="wrap_content"
  135.        android:text="加载图片"
  136.        android:textSize="40sp"/>
  137. </LinearLayout>  delay(100)
  138.     }
  139. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. MainScope-xxx
  4. CoroutineScope-1
  5. CoroutineScope-2
  6. MainScope-1
  7. MainScope-2
复制代码
​    说明:结果表明 job.join() 挂起了 MainScope 协程,直到 CoroutineScope 协程执行完毕才恢复执行。
4.4 异常处理处罚应用

4.4.1 try-catch 处理处罚异常
  1. fun main() {
  2.     println("main-start")
  3.     CoroutineScope(Dispatchers.IO).launch {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  try {
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  46. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  47.     xmlns:tools="http://schemas.android.com/tools"
  48.     android:layout_width="match_parent"
  49.     android:layout_height="match_parent"
  50.     tools:context=".MainActivity"
  51.     android:orientation="vertical"
  52.     android:gravity="center">
  53.    <ImageView
  54.        android:id="@+id/imageView"
  55.        android:layout_height="match_parent"
  56.        android:layout_width="match_parent"
  57.        android:scaleType="centerCrop"
  58.        android:visibility="gone" />
  59.    <Button
  60.        android:id="@+id/btn_back"
  61.        android:layout_width="250dp"
  62.        android:layout_height="wrap_content"
  63.        android:text="加载图片"
  64.        android:textSize="40sp"/>
  65. </LinearLayout>var a = 1 / 0
  66. <?xml version="1.0" encoding="utf-8"?>
  67. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  68.     xmlns:tools="http://schemas.android.com/tools"
  69.     android:layout_width="match_parent"
  70.     android:layout_height="match_parent"
  71.     tools:context=".MainActivity"
  72.     android:orientation="vertical"
  73.     android:gravity="center">
  74.    <ImageView
  75.        android:id="@+id/imageView"
  76.        android:layout_height="match_parent"
  77.        android:layout_width="match_parent"
  78.        android:scaleType="centerCrop"
  79.        android:visibility="gone" />
  80.    <Button
  81.        android:id="@+id/btn_back"
  82.        android:layout_width="250dp"
  83.        android:layout_height="wrap_content"
  84.        android:text="加载图片"
  85.        android:textSize="40sp"/>
  86. </LinearLayout>  } catch (e: Exception) {
  87. <?xml version="1.0" encoding="utf-8"?>
  88. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  89.     xmlns:tools="http://schemas.android.com/tools"
  90.     android:layout_width="match_parent"
  91.     android:layout_height="match_parent"
  92.     tools:context=".MainActivity"
  93.     android:orientation="vertical"
  94.     android:gravity="center">
  95.    <ImageView
  96.        android:id="@+id/imageView"
  97.        android:layout_height="match_parent"
  98.        android:layout_width="match_parent"
  99.        android:scaleType="centerCrop"
  100.        android:visibility="gone" />
  101.    <Button
  102.        android:id="@+id/btn_back"
  103.        android:layout_width="250dp"
  104.        android:layout_height="wrap_content"
  105.        android:text="加载图片"
  106.        android:textSize="40sp"/>
  107. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  108. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  109.     xmlns:tools="http://schemas.android.com/tools"
  110.     android:layout_width="match_parent"
  111.     android:layout_height="match_parent"
  112.     tools:context=".MainActivity"
  113.     android:orientation="vertical"
  114.     android:gravity="center">
  115.    <ImageView
  116.        android:id="@+id/imageView"
  117.        android:layout_height="match_parent"
  118.        android:layout_width="match_parent"
  119.        android:scaleType="centerCrop"
  120.        android:visibility="gone" />
  121.    <Button
  122.        android:id="@+id/btn_back"
  123.        android:layout_width="250dp"
  124.        android:layout_height="wrap_content"
  125.        android:text="加载图片"
  126.        android:textSize="40sp"/>
  127. </LinearLayout>println(e)
  128. <?xml version="1.0" encoding="utf-8"?>
  129. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  130.     xmlns:tools="http://schemas.android.com/tools"
  131.     android:layout_width="match_parent"
  132.     android:layout_height="match_parent"
  133.     tools:context=".MainActivity"
  134.     android:orientation="vertical"
  135.     android:gravity="center">
  136.    <ImageView
  137.        android:id="@+id/imageView"
  138.        android:layout_height="match_parent"
  139.        android:layout_width="match_parent"
  140.        android:scaleType="centerCrop"
  141.        android:visibility="gone" />
  142.    <Button
  143.        android:id="@+id/btn_back"
  144.        android:layout_width="250dp"
  145.        android:layout_height="wrap_content"
  146.        android:text="加载图片"
  147.        android:textSize="40sp"/>
  148. </LinearLayout>  }
  149.     }
  150.     println("main-end")
  151.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  152. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. java.lang.ArithmeticException: / by zero
复制代码
4.4.2 CoroutineExceptionHandler 处理处罚异常
  1. @OptIn(ExperimentalStdlibApi::class)
  2. fun main() {
  3.     println("main-start")
  4.     var exceptionHandler = CoroutineExceptionHandler { context, throwable ->
  5. <?xml version="1.0" encoding="utf-8"?>
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  7.     xmlns:tools="http://schemas.android.com/tools"
  8.     android:layout_width="match_parent"
  9.     android:layout_height="match_parent"
  10.     tools:context=".MainActivity"
  11.     android:orientation="vertical"
  12.     android:gravity="center">
  13.    <ImageView
  14.        android:id="@+id/imageView"
  15.        android:layout_height="match_parent"
  16.        android:layout_width="match_parent"
  17.        android:scaleType="centerCrop"
  18.        android:visibility="gone" />
  19.    <Button
  20.        android:id="@+id/btn_back"
  21.        android:layout_width="250dp"
  22.        android:layout_height="wrap_content"
  23.        android:text="加载图片"
  24.        android:textSize="40sp"/>
  25. </LinearLayout>  println("context=${context[CoroutineDispatcher]}, message=${throwable}")
  26.     }
  27.     CoroutineScope(Dispatchers.IO + exceptionHandler).launch {
  28. <?xml version="1.0" encoding="utf-8"?>
  29. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  30.     xmlns:tools="http://schemas.android.com/tools"
  31.     android:layout_width="match_parent"
  32.     android:layout_height="match_parent"
  33.     tools:context=".MainActivity"
  34.     android:orientation="vertical"
  35.     android:gravity="center">
  36.    <ImageView
  37.        android:id="@+id/imageView"
  38.        android:layout_height="match_parent"
  39.        android:layout_width="match_parent"
  40.        android:scaleType="centerCrop"
  41.        android:visibility="gone" />
  42.    <Button
  43.        android:id="@+id/btn_back"
  44.        android:layout_width="250dp"
  45.        android:layout_height="wrap_content"
  46.        android:text="加载图片"
  47.        android:textSize="40sp"/>
  48. </LinearLayout>  var a = 1 / 0
  49.     }
  50.     println("main-end")
  51.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  52. }
复制代码
​    打印如下。
  1. main-start
  2. main-end
  3. context=Dispatchers.IO, message=java.lang.ArithmeticException: / by zero
复制代码
5 协程并发安全

5.1 不安全的并发访问
  1. fun main() {
  2.     var count = 0
  3.     CoroutineScope(Dispatchers.Default).launch {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  var jobList = List(1000) { // 创建1000个子协程
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  46. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  47.     xmlns:tools="http://schemas.android.com/tools"
  48.     android:layout_width="match_parent"
  49.     android:layout_height="match_parent"
  50.     tools:context=".MainActivity"
  51.     android:orientation="vertical"
  52.     android:gravity="center">
  53.    <ImageView
  54.        android:id="@+id/imageView"
  55.        android:layout_height="match_parent"
  56.        android:layout_width="match_parent"
  57.        android:scaleType="centerCrop"
  58.        android:visibility="gone" />
  59.    <Button
  60.        android:id="@+id/btn_back"
  61.        android:layout_width="250dp"
  62.        android:layout_height="wrap_content"
  63.        android:text="加载图片"
  64.        android:textSize="40sp"/>
  65. </LinearLayout>CoroutineScope(Dispatchers.Default).launch {
  66. <?xml version="1.0" encoding="utf-8"?>
  67. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  68.     xmlns:tools="http://schemas.android.com/tools"
  69.     android:layout_width="match_parent"
  70.     android:layout_height="match_parent"
  71.     tools:context=".MainActivity"
  72.     android:orientation="vertical"
  73.     android:gravity="center">
  74.    <ImageView
  75.        android:id="@+id/imageView"
  76.        android:layout_height="match_parent"
  77.        android:layout_width="match_parent"
  78.        android:scaleType="centerCrop"
  79.        android:visibility="gone" />
  80.    <Button
  81.        android:id="@+id/btn_back"
  82.        android:layout_width="250dp"
  83.        android:layout_height="wrap_content"
  84.        android:text="加载图片"
  85.        android:textSize="40sp"/>
  86. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  87. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  88.     xmlns:tools="http://schemas.android.com/tools"
  89.     android:layout_width="match_parent"
  90.     android:layout_height="match_parent"
  91.     tools:context=".MainActivity"
  92.     android:orientation="vertical"
  93.     android:gravity="center">
  94.    <ImageView
  95.        android:id="@+id/imageView"
  96.        android:layout_height="match_parent"
  97.        android:layout_width="match_parent"
  98.        android:scaleType="centerCrop"
  99.        android:visibility="gone" />
  100.    <Button
  101.        android:id="@+id/btn_back"
  102.        android:layout_width="250dp"
  103.        android:layout_height="wrap_content"
  104.        android:text="加载图片"
  105.        android:textSize="40sp"/>
  106. </LinearLayout>    count++
  107. <?xml version="1.0" encoding="utf-8"?>
  108. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  109.     xmlns:tools="http://schemas.android.com/tools"
  110.     android:layout_width="match_parent"
  111.     android:layout_height="match_parent"
  112.     tools:context=".MainActivity"
  113.     android:orientation="vertical"
  114.     android:gravity="center">
  115.    <ImageView
  116.        android:id="@+id/imageView"
  117.        android:layout_height="match_parent"
  118.        android:layout_width="match_parent"
  119.        android:scaleType="centerCrop"
  120.        android:visibility="gone" />
  121.    <Button
  122.        android:id="@+id/btn_back"
  123.        android:layout_width="250dp"
  124.        android:layout_height="wrap_content"
  125.        android:text="加载图片"
  126.        android:textSize="40sp"/>
  127. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  128. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  129.     xmlns:tools="http://schemas.android.com/tools"
  130.     android:layout_width="match_parent"
  131.     android:layout_height="match_parent"
  132.     tools:context=".MainActivity"
  133.     android:orientation="vertical"
  134.     android:gravity="center">
  135.    <ImageView
  136.        android:id="@+id/imageView"
  137.        android:layout_height="match_parent"
  138.        android:layout_width="match_parent"
  139.        android:scaleType="centerCrop"
  140.        android:visibility="gone" />
  141.    <Button
  142.        android:id="@+id/btn_back"
  143.        android:layout_width="250dp"
  144.        android:layout_height="wrap_content"
  145.        android:text="加载图片"
  146.        android:textSize="40sp"/>
  147. </LinearLayout>}
  148. <?xml version="1.0" encoding="utf-8"?>
  149. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  150.     xmlns:tools="http://schemas.android.com/tools"
  151.     android:layout_width="match_parent"
  152.     android:layout_height="match_parent"
  153.     tools:context=".MainActivity"
  154.     android:orientation="vertical"
  155.     android:gravity="center">
  156.    <ImageView
  157.        android:id="@+id/imageView"
  158.        android:layout_height="match_parent"
  159.        android:layout_width="match_parent"
  160.        android:scaleType="centerCrop"
  161.        android:visibility="gone" />
  162.    <Button
  163.        android:id="@+id/btn_back"
  164.        android:layout_width="250dp"
  165.        android:layout_height="wrap_content"
  166.        android:text="加载图片"
  167.        android:textSize="40sp"/>
  168. </LinearLayout>  }
  169. <?xml version="1.0" encoding="utf-8"?>
  170. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  171.     xmlns:tools="http://schemas.android.com/tools"
  172.     android:layout_width="match_parent"
  173.     android:layout_height="match_parent"
  174.     tools:context=".MainActivity"
  175.     android:orientation="vertical"
  176.     android:gravity="center">
  177.    <ImageView
  178.        android:id="@+id/imageView"
  179.        android:layout_height="match_parent"
  180.        android:layout_width="match_parent"
  181.        android:scaleType="centerCrop"
  182.        android:visibility="gone" />
  183.    <Button
  184.        android:id="@+id/btn_back"
  185.        android:layout_width="250dp"
  186.        android:layout_height="wrap_content"
  187.        android:text="加载图片"
  188.        android:textSize="40sp"/>
  189. </LinearLayout>  jobList.joinAll() // 挂起当前协程, 直到所有子协程执行完成
  190. <?xml version="1.0" encoding="utf-8"?>
  191. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  192.     xmlns:tools="http://schemas.android.com/tools"
  193.     android:layout_width="match_parent"
  194.     android:layout_height="match_parent"
  195.     tools:context=".MainActivity"
  196.     android:orientation="vertical"
  197.     android:gravity="center">
  198.    <ImageView
  199.        android:id="@+id/imageView"
  200.        android:layout_height="match_parent"
  201.        android:layout_width="match_parent"
  202.        android:scaleType="centerCrop"
  203.        android:visibility="gone" />
  204.    <Button
  205.        android:id="@+id/btn_back"
  206.        android:layout_width="250dp"
  207.        android:layout_height="wrap_content"
  208.        android:text="加载图片"
  209.        android:textSize="40sp"/>
  210. </LinearLayout>  println(count) // 期望打印1000, 但每次运行结果不一样, 如:990、981、995等
  211.     }
  212.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  213. }
复制代码
5.2 安全的并发访问

​    安全的并发访问工具主要有 Atomic、Mutex、Semaphore、Channel。

  • Atomic:原子操纵,主要接口:getAndIncrement、getAndDecrement、getAndAdd、getAndAccumulate、incrementAndGet、decrementAndGet、addAndGet、accumulateAndGet 等。
  • Mutex:轻量级锁,主要接口:withLock 等。
  • Semaphore:轻量级信号量,主要接口:withPermit 等。
  • Channel:并发安全的消息通道,主要接口:send、receive。
5.2.1 Atomic

​    使用 Java 提供的原子操纵类型数据,如:AtomicBoolean、AtomicInteger、AtomicLong、AtomicIntegerArray、AtomicLongArray、AtomicReference、AtomicReferenceArray,可以解决一些并发安全访问的问题。
  1. fun main() {
  2.     var count = AtomicInteger()
  3.     CoroutineScope(Dispatchers.Default).launch {
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  6.     xmlns:tools="http://schemas.android.com/tools"
  7.     android:layout_width="match_parent"
  8.     android:layout_height="match_parent"
  9.     tools:context=".MainActivity"
  10.     android:orientation="vertical"
  11.     android:gravity="center">
  12.    <ImageView
  13.        android:id="@+id/imageView"
  14.        android:layout_height="match_parent"
  15.        android:layout_width="match_parent"
  16.        android:scaleType="centerCrop"
  17.        android:visibility="gone" />
  18.    <Button
  19.        android:id="@+id/btn_back"
  20.        android:layout_width="250dp"
  21.        android:layout_height="wrap_content"
  22.        android:text="加载图片"
  23.        android:textSize="40sp"/>
  24. </LinearLayout>  var jobList = List(1000) { // 创建1000个子协程
  25. <?xml version="1.0" encoding="utf-8"?>
  26. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  27.     xmlns:tools="http://schemas.android.com/tools"
  28.     android:layout_width="match_parent"
  29.     android:layout_height="match_parent"
  30.     tools:context=".MainActivity"
  31.     android:orientation="vertical"
  32.     android:gravity="center">
  33.    <ImageView
  34.        android:id="@+id/imageView"
  35.        android:layout_height="match_parent"
  36.        android:layout_width="match_parent"
  37.        android:scaleType="centerCrop"
  38.        android:visibility="gone" />
  39.    <Button
  40.        android:id="@+id/btn_back"
  41.        android:layout_width="250dp"
  42.        android:layout_height="wrap_content"
  43.        android:text="加载图片"
  44.        android:textSize="40sp"/>
  45. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  46. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  47.     xmlns:tools="http://schemas.android.com/tools"
  48.     android:layout_width="match_parent"
  49.     android:layout_height="match_parent"
  50.     tools:context=".MainActivity"
  51.     android:orientation="vertical"
  52.     android:gravity="center">
  53.    <ImageView
  54.        android:id="@+id/imageView"
  55.        android:layout_height="match_parent"
  56.        android:layout_width="match_parent"
  57.        android:scaleType="centerCrop"
  58.        android:visibility="gone" />
  59.    <Button
  60.        android:id="@+id/btn_back"
  61.        android:layout_width="250dp"
  62.        android:layout_height="wrap_content"
  63.        android:text="加载图片"
  64.        android:textSize="40sp"/>
  65. </LinearLayout>CoroutineScope(Dispatchers.Default).launch {
  66. <?xml version="1.0" encoding="utf-8"?>
  67. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  68.     xmlns:tools="http://schemas.android.com/tools"
  69.     android:layout_width="match_parent"
  70.     android:layout_height="match_parent"
  71.     tools:context=".MainActivity"
  72.     android:orientation="vertical"
  73.     android:gravity="center">
  74.    <ImageView
  75.        android:id="@+id/imageView"
  76.        android:layout_height="match_parent"
  77.        android:layout_width="match_parent"
  78.        android:scaleType="centerCrop"
  79.        android:visibility="gone" />
  80.    <Button
  81.        android:id="@+id/btn_back"
  82.        android:layout_width="250dp"
  83.        android:layout_height="wrap_content"
  84.        android:text="加载图片"
  85.        android:textSize="40sp"/>
  86. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  87. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  88.     xmlns:tools="http://schemas.android.com/tools"
  89.     android:layout_width="match_parent"
  90.     android:layout_height="match_parent"
  91.     tools:context=".MainActivity"
  92.     android:orientation="vertical"
  93.     android:gravity="center">
  94.    <ImageView
  95.        android:id="@+id/imageView"
  96.        android:layout_height="match_parent"
  97.        android:layout_width="match_parent"
  98.        android:scaleType="centerCrop"
  99.        android:visibility="gone" />
  100.    <Button
  101.        android:id="@+id/btn_back"
  102.        android:layout_width="250dp"
  103.        android:layout_height="wrap_content"
  104.        android:text="加载图片"
  105.        android:textSize="40sp"/>
  106. </LinearLayout>    count.getAndIncrement()
  107. <?xml version="1.0" encoding="utf-8"?>
  108. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  109.     xmlns:tools="http://schemas.android.com/tools"
  110.     android:layout_width="match_parent"
  111.     android:layout_height="match_parent"
  112.     tools:context=".MainActivity"
  113.     android:orientation="vertical"
  114.     android:gravity="center">
  115.    <ImageView
  116.        android:id="@+id/imageView"
  117.        android:layout_height="match_parent"
  118.        android:layout_width="match_parent"
  119.        android:scaleType="centerCrop"
  120.        android:visibility="gone" />
  121.    <Button
  122.        android:id="@+id/btn_back"
  123.        android:layout_width="250dp"
  124.        android:layout_height="wrap_content"
  125.        android:text="加载图片"
  126.        android:textSize="40sp"/>
  127. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  128. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  129.     xmlns:tools="http://schemas.android.com/tools"
  130.     android:layout_width="match_parent"
  131.     android:layout_height="match_parent"
  132.     tools:context=".MainActivity"
  133.     android:orientation="vertical"
  134.     android:gravity="center">
  135.    <ImageView
  136.        android:id="@+id/imageView"
  137.        android:layout_height="match_parent"
  138.        android:layout_width="match_parent"
  139.        android:scaleType="centerCrop"
  140.        android:visibility="gone" />
  141.    <Button
  142.        android:id="@+id/btn_back"
  143.        android:layout_width="250dp"
  144.        android:layout_height="wrap_content"
  145.        android:text="加载图片"
  146.        android:textSize="40sp"/>
  147. </LinearLayout>}
  148. <?xml version="1.0" encoding="utf-8"?>
  149. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  150.     xmlns:tools="http://schemas.android.com/tools"
  151.     android:layout_width="match_parent"
  152.     android:layout_height="match_parent"
  153.     tools:context=".MainActivity"
  154.     android:orientation="vertical"
  155.     android:gravity="center">
  156.    <ImageView
  157.        android:id="@+id/imageView"
  158.        android:layout_height="match_parent"
  159.        android:layout_width="match_parent"
  160.        android:scaleType="centerCrop"
  161.        android:visibility="gone" />
  162.    <Button
  163.        android:id="@+id/btn_back"
  164.        android:layout_width="250dp"
  165.        android:layout_height="wrap_content"
  166.        android:text="加载图片"
  167.        android:textSize="40sp"/>
  168. </LinearLayout>  }
  169. <?xml version="1.0" encoding="utf-8"?>
  170. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  171.     xmlns:tools="http://schemas.android.com/tools"
  172.     android:layout_width="match_parent"
  173.     android:layout_height="match_parent"
  174.     tools:context=".MainActivity"
  175.     android:orientation="vertical"
  176.     android:gravity="center">
  177.    <ImageView
  178.        android:id="@+id/imageView"
  179.        android:layout_height="match_parent"
  180.        android:layout_width="match_parent"
  181.        android:scaleType="centerCrop"
  182.        android:visibility="gone" />
  183.    <Button
  184.        android:id="@+id/btn_back"
  185.        android:layout_width="250dp"
  186.        android:layout_height="wrap_content"
  187.        android:text="加载图片"
  188.        android:textSize="40sp"/>
  189. </LinearLayout>  jobList.joinAll() // 挂起当前协程, 直到所有子协程执行完成
  190. <?xml version="1.0" encoding="utf-8"?>
  191. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  192.     xmlns:tools="http://schemas.android.com/tools"
  193.     android:layout_width="match_parent"
  194.     android:layout_height="match_parent"
  195.     tools:context=".MainActivity"
  196.     android:orientation="vertical"
  197.     android:gravity="center">
  198.    <ImageView
  199.        android:id="@+id/imageView"
  200.        android:layout_height="match_parent"
  201.        android:layout_width="match_parent"
  202.        android:scaleType="centerCrop"
  203.        android:visibility="gone" />
  204.    <Button
  205.        android:id="@+id/btn_back"
  206.        android:layout_width="250dp"
  207.        android:layout_height="wrap_content"
  208.        android:text="加载图片"
  209.        android:textSize="40sp"/>
  210. </LinearLayout>  println(count.get()) // 打印: 1000
  211.     }
  212.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  213. }
复制代码
5.2.2 Mutex

​    Mutex 是轻量级锁,它的 lock 和 unlock 从语义上与线程锁比较类似,之所以轻量是由于它在获取不到锁时不会阻塞线程,而是挂起等候锁的释放。
  1. fun main() {
  2.     var count = 0
  3.     var mutex = Mutex()
  4.     CoroutineScope(Dispatchers.Default).launch {
  5. <?xml version="1.0" encoding="utf-8"?>
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  7.     xmlns:tools="http://schemas.android.com/tools"
  8.     android:layout_width="match_parent"
  9.     android:layout_height="match_parent"
  10.     tools:context=".MainActivity"
  11.     android:orientation="vertical"
  12.     android:gravity="center">
  13.    <ImageView
  14.        android:id="@+id/imageView"
  15.        android:layout_height="match_parent"
  16.        android:layout_width="match_parent"
  17.        android:scaleType="centerCrop"
  18.        android:visibility="gone" />
  19.    <Button
  20.        android:id="@+id/btn_back"
  21.        android:layout_width="250dp"
  22.        android:layout_height="wrap_content"
  23.        android:text="加载图片"
  24.        android:textSize="40sp"/>
  25. </LinearLayout>  var jobList = List(1000) { // 创建1000个子协程
  26. <?xml version="1.0" encoding="utf-8"?>
  27. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  28.     xmlns:tools="http://schemas.android.com/tools"
  29.     android:layout_width="match_parent"
  30.     android:layout_height="match_parent"
  31.     tools:context=".MainActivity"
  32.     android:orientation="vertical"
  33.     android:gravity="center">
  34.    <ImageView
  35.        android:id="@+id/imageView"
  36.        android:layout_height="match_parent"
  37.        android:layout_width="match_parent"
  38.        android:scaleType="centerCrop"
  39.        android:visibility="gone" />
  40.    <Button
  41.        android:id="@+id/btn_back"
  42.        android:layout_width="250dp"
  43.        android:layout_height="wrap_content"
  44.        android:text="加载图片"
  45.        android:textSize="40sp"/>
  46. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  47. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  48.     xmlns:tools="http://schemas.android.com/tools"
  49.     android:layout_width="match_parent"
  50.     android:layout_height="match_parent"
  51.     tools:context=".MainActivity"
  52.     android:orientation="vertical"
  53.     android:gravity="center">
  54.    <ImageView
  55.        android:id="@+id/imageView"
  56.        android:layout_height="match_parent"
  57.        android:layout_width="match_parent"
  58.        android:scaleType="centerCrop"
  59.        android:visibility="gone" />
  60.    <Button
  61.        android:id="@+id/btn_back"
  62.        android:layout_width="250dp"
  63.        android:layout_height="wrap_content"
  64.        android:text="加载图片"
  65.        android:textSize="40sp"/>
  66. </LinearLayout>CoroutineScope(Dispatchers.Default).launch {
  67. <?xml version="1.0" encoding="utf-8"?>
  68. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  69.     xmlns:tools="http://schemas.android.com/tools"
  70.     android:layout_width="match_parent"
  71.     android:layout_height="match_parent"
  72.     tools:context=".MainActivity"
  73.     android:orientation="vertical"
  74.     android:gravity="center">
  75.    <ImageView
  76.        android:id="@+id/imageView"
  77.        android:layout_height="match_parent"
  78.        android:layout_width="match_parent"
  79.        android:scaleType="centerCrop"
  80.        android:visibility="gone" />
  81.    <Button
  82.        android:id="@+id/btn_back"
  83.        android:layout_width="250dp"
  84.        android:layout_height="wrap_content"
  85.        android:text="加载图片"
  86.        android:textSize="40sp"/>
  87. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  88. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  89.     xmlns:tools="http://schemas.android.com/tools"
  90.     android:layout_width="match_parent"
  91.     android:layout_height="match_parent"
  92.     tools:context=".MainActivity"
  93.     android:orientation="vertical"
  94.     android:gravity="center">
  95.    <ImageView
  96.        android:id="@+id/imageView"
  97.        android:layout_height="match_parent"
  98.        android:layout_width="match_parent"
  99.        android:scaleType="centerCrop"
  100.        android:visibility="gone" />
  101.    <Button
  102.        android:id="@+id/btn_back"
  103.        android:layout_width="250dp"
  104.        android:layout_height="wrap_content"
  105.        android:text="加载图片"
  106.        android:textSize="40sp"/>
  107. </LinearLayout>    mutex.withLock {
  108. <?xml version="1.0" encoding="utf-8"?>
  109. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  110.     xmlns:tools="http://schemas.android.com/tools"
  111.     android:layout_width="match_parent"
  112.     android:layout_height="match_parent"
  113.     tools:context=".MainActivity"
  114.     android:orientation="vertical"
  115.     android:gravity="center">
  116.    <ImageView
  117.        android:id="@+id/imageView"
  118.        android:layout_height="match_parent"
  119.        android:layout_width="match_parent"
  120.        android:scaleType="centerCrop"
  121.        android:visibility="gone" />
  122.    <Button
  123.        android:id="@+id/btn_back"
  124.        android:layout_width="250dp"
  125.        android:layout_height="wrap_content"
  126.        android:text="加载图片"
  127.        android:textSize="40sp"/>
  128. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  129. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  130.     xmlns:tools="http://schemas.android.com/tools"
  131.     android:layout_width="match_parent"
  132.     android:layout_height="match_parent"
  133.     tools:context=".MainActivity"
  134.     android:orientation="vertical"
  135.     android:gravity="center">
  136.    <ImageView
  137.        android:id="@+id/imageView"
  138.        android:layout_height="match_parent"
  139.        android:layout_width="match_parent"
  140.        android:scaleType="centerCrop"
  141.        android:visibility="gone" />
  142.    <Button
  143.        android:id="@+id/btn_back"
  144.        android:layout_width="250dp"
  145.        android:layout_height="wrap_content"
  146.        android:text="加载图片"
  147.        android:textSize="40sp"/>
  148. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  149. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  150.     xmlns:tools="http://schemas.android.com/tools"
  151.     android:layout_width="match_parent"
  152.     android:layout_height="match_parent"
  153.     tools:context=".MainActivity"
  154.     android:orientation="vertical"
  155.     android:gravity="center">
  156.    <ImageView
  157.        android:id="@+id/imageView"
  158.        android:layout_height="match_parent"
  159.        android:layout_width="match_parent"
  160.        android:scaleType="centerCrop"
  161.        android:visibility="gone" />
  162.    <Button
  163.        android:id="@+id/btn_back"
  164.        android:layout_width="250dp"
  165.        android:layout_height="wrap_content"
  166.        android:text="加载图片"
  167.        android:textSize="40sp"/>
  168. </LinearLayout>  count++
  169. <?xml version="1.0" encoding="utf-8"?>
  170. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  171.     xmlns:tools="http://schemas.android.com/tools"
  172.     android:layout_width="match_parent"
  173.     android:layout_height="match_parent"
  174.     tools:context=".MainActivity"
  175.     android:orientation="vertical"
  176.     android:gravity="center">
  177.    <ImageView
  178.        android:id="@+id/imageView"
  179.        android:layout_height="match_parent"
  180.        android:layout_width="match_parent"
  181.        android:scaleType="centerCrop"
  182.        android:visibility="gone" />
  183.    <Button
  184.        android:id="@+id/btn_back"
  185.        android:layout_width="250dp"
  186.        android:layout_height="wrap_content"
  187.        android:text="加载图片"
  188.        android:textSize="40sp"/>
  189. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  190. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  191.     xmlns:tools="http://schemas.android.com/tools"
  192.     android:layout_width="match_parent"
  193.     android:layout_height="match_parent"
  194.     tools:context=".MainActivity"
  195.     android:orientation="vertical"
  196.     android:gravity="center">
  197.    <ImageView
  198.        android:id="@+id/imageView"
  199.        android:layout_height="match_parent"
  200.        android:layout_width="match_parent"
  201.        android:scaleType="centerCrop"
  202.        android:visibility="gone" />
  203.    <Button
  204.        android:id="@+id/btn_back"
  205.        android:layout_width="250dp"
  206.        android:layout_height="wrap_content"
  207.        android:text="加载图片"
  208.        android:textSize="40sp"/>
  209. </LinearLayout>    }
  210. <?xml version="1.0" encoding="utf-8"?>
  211. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  212.     xmlns:tools="http://schemas.android.com/tools"
  213.     android:layout_width="match_parent"
  214.     android:layout_height="match_parent"
  215.     tools:context=".MainActivity"
  216.     android:orientation="vertical"
  217.     android:gravity="center">
  218.    <ImageView
  219.        android:id="@+id/imageView"
  220.        android:layout_height="match_parent"
  221.        android:layout_width="match_parent"
  222.        android:scaleType="centerCrop"
  223.        android:visibility="gone" />
  224.    <Button
  225.        android:id="@+id/btn_back"
  226.        android:layout_width="250dp"
  227.        android:layout_height="wrap_content"
  228.        android:text="加载图片"
  229.        android:textSize="40sp"/>
  230. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  231. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  232.     xmlns:tools="http://schemas.android.com/tools"
  233.     android:layout_width="match_parent"
  234.     android:layout_height="match_parent"
  235.     tools:context=".MainActivity"
  236.     android:orientation="vertical"
  237.     android:gravity="center">
  238.    <ImageView
  239.        android:id="@+id/imageView"
  240.        android:layout_height="match_parent"
  241.        android:layout_width="match_parent"
  242.        android:scaleType="centerCrop"
  243.        android:visibility="gone" />
  244.    <Button
  245.        android:id="@+id/btn_back"
  246.        android:layout_width="250dp"
  247.        android:layout_height="wrap_content"
  248.        android:text="加载图片"
  249.        android:textSize="40sp"/>
  250. </LinearLayout>}
  251. <?xml version="1.0" encoding="utf-8"?>
  252. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  253.     xmlns:tools="http://schemas.android.com/tools"
  254.     android:layout_width="match_parent"
  255.     android:layout_height="match_parent"
  256.     tools:context=".MainActivity"
  257.     android:orientation="vertical"
  258.     android:gravity="center">
  259.    <ImageView
  260.        android:id="@+id/imageView"
  261.        android:layout_height="match_parent"
  262.        android:layout_width="match_parent"
  263.        android:scaleType="centerCrop"
  264.        android:visibility="gone" />
  265.    <Button
  266.        android:id="@+id/btn_back"
  267.        android:layout_width="250dp"
  268.        android:layout_height="wrap_content"
  269.        android:text="加载图片"
  270.        android:textSize="40sp"/>
  271. </LinearLayout>  }
  272. <?xml version="1.0" encoding="utf-8"?>
  273. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  274.     xmlns:tools="http://schemas.android.com/tools"
  275.     android:layout_width="match_parent"
  276.     android:layout_height="match_parent"
  277.     tools:context=".MainActivity"
  278.     android:orientation="vertical"
  279.     android:gravity="center">
  280.    <ImageView
  281.        android:id="@+id/imageView"
  282.        android:layout_height="match_parent"
  283.        android:layout_width="match_parent"
  284.        android:scaleType="centerCrop"
  285.        android:visibility="gone" />
  286.    <Button
  287.        android:id="@+id/btn_back"
  288.        android:layout_width="250dp"
  289.        android:layout_height="wrap_content"
  290.        android:text="加载图片"
  291.        android:textSize="40sp"/>
  292. </LinearLayout>  jobList.joinAll() // 挂起当前协程, 直到所有子协程执行完成
  293. <?xml version="1.0" encoding="utf-8"?>
  294. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  295.     xmlns:tools="http://schemas.android.com/tools"
  296.     android:layout_width="match_parent"
  297.     android:layout_height="match_parent"
  298.     tools:context=".MainActivity"
  299.     android:orientation="vertical"
  300.     android:gravity="center">
  301.    <ImageView
  302.        android:id="@+id/imageView"
  303.        android:layout_height="match_parent"
  304.        android:layout_width="match_parent"
  305.        android:scaleType="centerCrop"
  306.        android:visibility="gone" />
  307.    <Button
  308.        android:id="@+id/btn_back"
  309.        android:layout_width="250dp"
  310.        android:layout_height="wrap_content"
  311.        android:text="加载图片"
  312.        android:textSize="40sp"/>
  313. </LinearLayout>  println(count) // 打印: 1000
  314.     }
  315.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  316. }
复制代码
5.2.3 Semaphore

​    Semaphore 是轻量级信号量,信号可以有多个,协程在获取到信号后即可执行并发操纵。
  1. fun main() {
  2.     var count = 0
  3.     var semaphore = Semaphore(1) // 创建一个信号量, 里面只有一个信号
  4.     CoroutineScope(Dispatchers.Default).launch {
  5. <?xml version="1.0" encoding="utf-8"?>
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  7.     xmlns:tools="http://schemas.android.com/tools"
  8.     android:layout_width="match_parent"
  9.     android:layout_height="match_parent"
  10.     tools:context=".MainActivity"
  11.     android:orientation="vertical"
  12.     android:gravity="center">
  13.    <ImageView
  14.        android:id="@+id/imageView"
  15.        android:layout_height="match_parent"
  16.        android:layout_width="match_parent"
  17.        android:scaleType="centerCrop"
  18.        android:visibility="gone" />
  19.    <Button
  20.        android:id="@+id/btn_back"
  21.        android:layout_width="250dp"
  22.        android:layout_height="wrap_content"
  23.        android:text="加载图片"
  24.        android:textSize="40sp"/>
  25. </LinearLayout>  var jobList = List(1000) { // 创建1000个子协程
  26. <?xml version="1.0" encoding="utf-8"?>
  27. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  28.     xmlns:tools="http://schemas.android.com/tools"
  29.     android:layout_width="match_parent"
  30.     android:layout_height="match_parent"
  31.     tools:context=".MainActivity"
  32.     android:orientation="vertical"
  33.     android:gravity="center">
  34.    <ImageView
  35.        android:id="@+id/imageView"
  36.        android:layout_height="match_parent"
  37.        android:layout_width="match_parent"
  38.        android:scaleType="centerCrop"
  39.        android:visibility="gone" />
  40.    <Button
  41.        android:id="@+id/btn_back"
  42.        android:layout_width="250dp"
  43.        android:layout_height="wrap_content"
  44.        android:text="加载图片"
  45.        android:textSize="40sp"/>
  46. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  47. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  48.     xmlns:tools="http://schemas.android.com/tools"
  49.     android:layout_width="match_parent"
  50.     android:layout_height="match_parent"
  51.     tools:context=".MainActivity"
  52.     android:orientation="vertical"
  53.     android:gravity="center">
  54.    <ImageView
  55.        android:id="@+id/imageView"
  56.        android:layout_height="match_parent"
  57.        android:layout_width="match_parent"
  58.        android:scaleType="centerCrop"
  59.        android:visibility="gone" />
  60.    <Button
  61.        android:id="@+id/btn_back"
  62.        android:layout_width="250dp"
  63.        android:layout_height="wrap_content"
  64.        android:text="加载图片"
  65.        android:textSize="40sp"/>
  66. </LinearLayout>CoroutineScope(Dispatchers.Default).launch {
  67. <?xml version="1.0" encoding="utf-8"?>
  68. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  69.     xmlns:tools="http://schemas.android.com/tools"
  70.     android:layout_width="match_parent"
  71.     android:layout_height="match_parent"
  72.     tools:context=".MainActivity"
  73.     android:orientation="vertical"
  74.     android:gravity="center">
  75.    <ImageView
  76.        android:id="@+id/imageView"
  77.        android:layout_height="match_parent"
  78.        android:layout_width="match_parent"
  79.        android:scaleType="centerCrop"
  80.        android:visibility="gone" />
  81.    <Button
  82.        android:id="@+id/btn_back"
  83.        android:layout_width="250dp"
  84.        android:layout_height="wrap_content"
  85.        android:text="加载图片"
  86.        android:textSize="40sp"/>
  87. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  88. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  89.     xmlns:tools="http://schemas.android.com/tools"
  90.     android:layout_width="match_parent"
  91.     android:layout_height="match_parent"
  92.     tools:context=".MainActivity"
  93.     android:orientation="vertical"
  94.     android:gravity="center">
  95.    <ImageView
  96.        android:id="@+id/imageView"
  97.        android:layout_height="match_parent"
  98.        android:layout_width="match_parent"
  99.        android:scaleType="centerCrop"
  100.        android:visibility="gone" />
  101.    <Button
  102.        android:id="@+id/btn_back"
  103.        android:layout_width="250dp"
  104.        android:layout_height="wrap_content"
  105.        android:text="加载图片"
  106.        android:textSize="40sp"/>
  107. </LinearLayout>    semaphore.withPermit {
  108. <?xml version="1.0" encoding="utf-8"?>
  109. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  110.     xmlns:tools="http://schemas.android.com/tools"
  111.     android:layout_width="match_parent"
  112.     android:layout_height="match_parent"
  113.     tools:context=".MainActivity"
  114.     android:orientation="vertical"
  115.     android:gravity="center">
  116.    <ImageView
  117.        android:id="@+id/imageView"
  118.        android:layout_height="match_parent"
  119.        android:layout_width="match_parent"
  120.        android:scaleType="centerCrop"
  121.        android:visibility="gone" />
  122.    <Button
  123.        android:id="@+id/btn_back"
  124.        android:layout_width="250dp"
  125.        android:layout_height="wrap_content"
  126.        android:text="加载图片"
  127.        android:textSize="40sp"/>
  128. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  129. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  130.     xmlns:tools="http://schemas.android.com/tools"
  131.     android:layout_width="match_parent"
  132.     android:layout_height="match_parent"
  133.     tools:context=".MainActivity"
  134.     android:orientation="vertical"
  135.     android:gravity="center">
  136.    <ImageView
  137.        android:id="@+id/imageView"
  138.        android:layout_height="match_parent"
  139.        android:layout_width="match_parent"
  140.        android:scaleType="centerCrop"
  141.        android:visibility="gone" />
  142.    <Button
  143.        android:id="@+id/btn_back"
  144.        android:layout_width="250dp"
  145.        android:layout_height="wrap_content"
  146.        android:text="加载图片"
  147.        android:textSize="40sp"/>
  148. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  149. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  150.     xmlns:tools="http://schemas.android.com/tools"
  151.     android:layout_width="match_parent"
  152.     android:layout_height="match_parent"
  153.     tools:context=".MainActivity"
  154.     android:orientation="vertical"
  155.     android:gravity="center">
  156.    <ImageView
  157.        android:id="@+id/imageView"
  158.        android:layout_height="match_parent"
  159.        android:layout_width="match_parent"
  160.        android:scaleType="centerCrop"
  161.        android:visibility="gone" />
  162.    <Button
  163.        android:id="@+id/btn_back"
  164.        android:layout_width="250dp"
  165.        android:layout_height="wrap_content"
  166.        android:text="加载图片"
  167.        android:textSize="40sp"/>
  168. </LinearLayout>  count++
  169. <?xml version="1.0" encoding="utf-8"?>
  170. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  171.     xmlns:tools="http://schemas.android.com/tools"
  172.     android:layout_width="match_parent"
  173.     android:layout_height="match_parent"
  174.     tools:context=".MainActivity"
  175.     android:orientation="vertical"
  176.     android:gravity="center">
  177.    <ImageView
  178.        android:id="@+id/imageView"
  179.        android:layout_height="match_parent"
  180.        android:layout_width="match_parent"
  181.        android:scaleType="centerCrop"
  182.        android:visibility="gone" />
  183.    <Button
  184.        android:id="@+id/btn_back"
  185.        android:layout_width="250dp"
  186.        android:layout_height="wrap_content"
  187.        android:text="加载图片"
  188.        android:textSize="40sp"/>
  189. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  190. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  191.     xmlns:tools="http://schemas.android.com/tools"
  192.     android:layout_width="match_parent"
  193.     android:layout_height="match_parent"
  194.     tools:context=".MainActivity"
  195.     android:orientation="vertical"
  196.     android:gravity="center">
  197.    <ImageView
  198.        android:id="@+id/imageView"
  199.        android:layout_height="match_parent"
  200.        android:layout_width="match_parent"
  201.        android:scaleType="centerCrop"
  202.        android:visibility="gone" />
  203.    <Button
  204.        android:id="@+id/btn_back"
  205.        android:layout_width="250dp"
  206.        android:layout_height="wrap_content"
  207.        android:text="加载图片"
  208.        android:textSize="40sp"/>
  209. </LinearLayout>    }
  210. <?xml version="1.0" encoding="utf-8"?>
  211. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  212.     xmlns:tools="http://schemas.android.com/tools"
  213.     android:layout_width="match_parent"
  214.     android:layout_height="match_parent"
  215.     tools:context=".MainActivity"
  216.     android:orientation="vertical"
  217.     android:gravity="center">
  218.    <ImageView
  219.        android:id="@+id/imageView"
  220.        android:layout_height="match_parent"
  221.        android:layout_width="match_parent"
  222.        android:scaleType="centerCrop"
  223.        android:visibility="gone" />
  224.    <Button
  225.        android:id="@+id/btn_back"
  226.        android:layout_width="250dp"
  227.        android:layout_height="wrap_content"
  228.        android:text="加载图片"
  229.        android:textSize="40sp"/>
  230. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  231. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  232.     xmlns:tools="http://schemas.android.com/tools"
  233.     android:layout_width="match_parent"
  234.     android:layout_height="match_parent"
  235.     tools:context=".MainActivity"
  236.     android:orientation="vertical"
  237.     android:gravity="center">
  238.    <ImageView
  239.        android:id="@+id/imageView"
  240.        android:layout_height="match_parent"
  241.        android:layout_width="match_parent"
  242.        android:scaleType="centerCrop"
  243.        android:visibility="gone" />
  244.    <Button
  245.        android:id="@+id/btn_back"
  246.        android:layout_width="250dp"
  247.        android:layout_height="wrap_content"
  248.        android:text="加载图片"
  249.        android:textSize="40sp"/>
  250. </LinearLayout>}
  251. <?xml version="1.0" encoding="utf-8"?>
  252. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  253.     xmlns:tools="http://schemas.android.com/tools"
  254.     android:layout_width="match_parent"
  255.     android:layout_height="match_parent"
  256.     tools:context=".MainActivity"
  257.     android:orientation="vertical"
  258.     android:gravity="center">
  259.    <ImageView
  260.        android:id="@+id/imageView"
  261.        android:layout_height="match_parent"
  262.        android:layout_width="match_parent"
  263.        android:scaleType="centerCrop"
  264.        android:visibility="gone" />
  265.    <Button
  266.        android:id="@+id/btn_back"
  267.        android:layout_width="250dp"
  268.        android:layout_height="wrap_content"
  269.        android:text="加载图片"
  270.        android:textSize="40sp"/>
  271. </LinearLayout>  }
  272. <?xml version="1.0" encoding="utf-8"?>
  273. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  274.     xmlns:tools="http://schemas.android.com/tools"
  275.     android:layout_width="match_parent"
  276.     android:layout_height="match_parent"
  277.     tools:context=".MainActivity"
  278.     android:orientation="vertical"
  279.     android:gravity="center">
  280.    <ImageView
  281.        android:id="@+id/imageView"
  282.        android:layout_height="match_parent"
  283.        android:layout_width="match_parent"
  284.        android:scaleType="centerCrop"
  285.        android:visibility="gone" />
  286.    <Button
  287.        android:id="@+id/btn_back"
  288.        android:layout_width="250dp"
  289.        android:layout_height="wrap_content"
  290.        android:text="加载图片"
  291.        android:textSize="40sp"/>
  292. </LinearLayout>  jobList.joinAll() // 挂起当前协程, 直到所有子协程执行完成
  293. <?xml version="1.0" encoding="utf-8"?>
  294. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  295.     xmlns:tools="http://schemas.android.com/tools"
  296.     android:layout_width="match_parent"
  297.     android:layout_height="match_parent"
  298.     tools:context=".MainActivity"
  299.     android:orientation="vertical"
  300.     android:gravity="center">
  301.    <ImageView
  302.        android:id="@+id/imageView"
  303.        android:layout_height="match_parent"
  304.        android:layout_width="match_parent"
  305.        android:scaleType="centerCrop"
  306.        android:visibility="gone" />
  307.    <Button
  308.        android:id="@+id/btn_back"
  309.        android:layout_width="250dp"
  310.        android:layout_height="wrap_content"
  311.        android:text="加载图片"
  312.        android:textSize="40sp"/>
  313. </LinearLayout>  println(count) // 打印: 1000
  314.     }
  315.     Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
  316. }
复制代码
​    说明:Semaphore 的入参表示信号个数,当 Semaphore 的参数为 1 时, 效果等价与 Mutex。
6 加载网络图片案例

​    build.gradle 中需要引入以下依赖。
  1. dependencies {
  2.     implementation 'com.github.bumptech.glide:glide:4.12.0'
  3.     implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
  4.     ...
  5. }
复制代码
​    AndroidManifest.xml 中需要设置以下权限。
  1. [/code]​    MainActivity.kt
  2. [code]package com.zhyan8.kotlinStudy
  3. import android.os.Bundle
  4. import android.view.View
  5. import android.widget.Button
  6. import android.widget.ImageView
  7. import androidx.appcompat.app.AppCompatActivity
  8. import androidx.lifecycle.lifecycleScope
  9. import com.bumptech.glide.Glide
  10. import kotlinx.coroutines.Dispatchers
  11. import kotlinx.coroutines.launch
  12. import kotlinx.coroutines.withContext
  13. class MainActivity: AppCompatActivity() {
  14.     private lateinit var imageView: ImageView
  15.     private lateinit var button: Button
  16.     override fun onCreate(savedInstanceState: Bundle?) {
  17. <?xml version="1.0" encoding="utf-8"?>
  18. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  19.     xmlns:tools="http://schemas.android.com/tools"
  20.     android:layout_width="match_parent"
  21.     android:layout_height="match_parent"
  22.     tools:context=".MainActivity"
  23.     android:orientation="vertical"
  24.     android:gravity="center">
  25.    <ImageView
  26.        android:id="@+id/imageView"
  27.        android:layout_height="match_parent"
  28.        android:layout_width="match_parent"
  29.        android:scaleType="centerCrop"
  30.        android:visibility="gone" />
  31.    <Button
  32.        android:id="@+id/btn_back"
  33.        android:layout_width="250dp"
  34.        android:layout_height="wrap_content"
  35.        android:text="加载图片"
  36.        android:textSize="40sp"/>
  37. </LinearLayout>  super.onCreate(savedInstanceState)
  38. <?xml version="1.0" encoding="utf-8"?>
  39. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  40.     xmlns:tools="http://schemas.android.com/tools"
  41.     android:layout_width="match_parent"
  42.     android:layout_height="match_parent"
  43.     tools:context=".MainActivity"
  44.     android:orientation="vertical"
  45.     android:gravity="center">
  46.    <ImageView
  47.        android:id="@+id/imageView"
  48.        android:layout_height="match_parent"
  49.        android:layout_width="match_parent"
  50.        android:scaleType="centerCrop"
  51.        android:visibility="gone" />
  52.    <Button
  53.        android:id="@+id/btn_back"
  54.        android:layout_width="250dp"
  55.        android:layout_height="wrap_content"
  56.        android:text="加载图片"
  57.        android:textSize="40sp"/>
  58. </LinearLayout>  setContentView(R.layout.activity_main)
  59. <?xml version="1.0" encoding="utf-8"?>
  60. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  61.     xmlns:tools="http://schemas.android.com/tools"
  62.     android:layout_width="match_parent"
  63.     android:layout_height="match_parent"
  64.     tools:context=".MainActivity"
  65.     android:orientation="vertical"
  66.     android:gravity="center">
  67.    <ImageView
  68.        android:id="@+id/imageView"
  69.        android:layout_height="match_parent"
  70.        android:layout_width="match_parent"
  71.        android:scaleType="centerCrop"
  72.        android:visibility="gone" />
  73.    <Button
  74.        android:id="@+id/btn_back"
  75.        android:layout_width="250dp"
  76.        android:layout_height="wrap_content"
  77.        android:text="加载图片"
  78.        android:textSize="40sp"/>
  79. </LinearLayout>  imageView = findViewById(R.id.imageView)
  80. <?xml version="1.0" encoding="utf-8"?>
  81. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  82.     xmlns:tools="http://schemas.android.com/tools"
  83.     android:layout_width="match_parent"
  84.     android:layout_height="match_parent"
  85.     tools:context=".MainActivity"
  86.     android:orientation="vertical"
  87.     android:gravity="center">
  88.    <ImageView
  89.        android:id="@+id/imageView"
  90.        android:layout_height="match_parent"
  91.        android:layout_width="match_parent"
  92.        android:scaleType="centerCrop"
  93.        android:visibility="gone" />
  94.    <Button
  95.        android:id="@+id/btn_back"
  96.        android:layout_width="250dp"
  97.        android:layout_height="wrap_content"
  98.        android:text="加载图片"
  99.        android:textSize="40sp"/>
  100. </LinearLayout>  button = findViewById(R.id.btn_back)
  101. <?xml version="1.0" encoding="utf-8"?>
  102. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  103.     xmlns:tools="http://schemas.android.com/tools"
  104.     android:layout_width="match_parent"
  105.     android:layout_height="match_parent"
  106.     tools:context=".MainActivity"
  107.     android:orientation="vertical"
  108.     android:gravity="center">
  109.    <ImageView
  110.        android:id="@+id/imageView"
  111.        android:layout_height="match_parent"
  112.        android:layout_width="match_parent"
  113.        android:scaleType="centerCrop"
  114.        android:visibility="gone" />
  115.    <Button
  116.        android:id="@+id/btn_back"
  117.        android:layout_width="250dp"
  118.        android:layout_height="wrap_content"
  119.        android:text="加载图片"
  120.        android:textSize="40sp"/>
  121. </LinearLayout>  button.setOnClickListener{
  122. <?xml version="1.0" encoding="utf-8"?>
  123. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  124.     xmlns:tools="http://schemas.android.com/tools"
  125.     android:layout_width="match_parent"
  126.     android:layout_height="match_parent"
  127.     tools:context=".MainActivity"
  128.     android:orientation="vertical"
  129.     android:gravity="center">
  130.    <ImageView
  131.        android:id="@+id/imageView"
  132.        android:layout_height="match_parent"
  133.        android:layout_width="match_parent"
  134.        android:scaleType="centerCrop"
  135.        android:visibility="gone" />
  136.    <Button
  137.        android:id="@+id/btn_back"
  138.        android:layout_width="250dp"
  139.        android:layout_height="wrap_content"
  140.        android:text="加载图片"
  141.        android:textSize="40sp"/>
  142. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  143. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  144.     xmlns:tools="http://schemas.android.com/tools"
  145.     android:layout_width="match_parent"
  146.     android:layout_height="match_parent"
  147.     tools:context=".MainActivity"
  148.     android:orientation="vertical"
  149.     android:gravity="center">
  150.    <ImageView
  151.        android:id="@+id/imageView"
  152.        android:layout_height="match_parent"
  153.        android:layout_width="match_parent"
  154.        android:scaleType="centerCrop"
  155.        android:visibility="gone" />
  156.    <Button
  157.        android:id="@+id/btn_back"
  158.        android:layout_width="250dp"
  159.        android:layout_height="wrap_content"
  160.        android:text="加载图片"
  161.        android:textSize="40sp"/>
  162. </LinearLayout>lifecycleScope.launch(Dispatchers.IO) {
  163. <?xml version="1.0" encoding="utf-8"?>
  164. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  165.     xmlns:tools="http://schemas.android.com/tools"
  166.     android:layout_width="match_parent"
  167.     android:layout_height="match_parent"
  168.     tools:context=".MainActivity"
  169.     android:orientation="vertical"
  170.     android:gravity="center">
  171.    <ImageView
  172.        android:id="@+id/imageView"
  173.        android:layout_height="match_parent"
  174.        android:layout_width="match_parent"
  175.        android:scaleType="centerCrop"
  176.        android:visibility="gone" />
  177.    <Button
  178.        android:id="@+id/btn_back"
  179.        android:layout_width="250dp"
  180.        android:layout_height="wrap_content"
  181.        android:text="加载图片"
  182.        android:textSize="40sp"/>
  183. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  184. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  185.     xmlns:tools="http://schemas.android.com/tools"
  186.     android:layout_width="match_parent"
  187.     android:layout_height="match_parent"
  188.     tools:context=".MainActivity"
  189.     android:orientation="vertical"
  190.     android:gravity="center">
  191.    <ImageView
  192.        android:id="@+id/imageView"
  193.        android:layout_height="match_parent"
  194.        android:layout_width="match_parent"
  195.        android:scaleType="centerCrop"
  196.        android:visibility="gone" />
  197.    <Button
  198.        android:id="@+id/btn_back"
  199.        android:layout_width="250dp"
  200.        android:layout_height="wrap_content"
  201.        android:text="加载图片"
  202.        android:textSize="40sp"/>
  203. </LinearLayout>    loadImageFromUrl("https://images.cnblogs.com/cnblogs_com/blogs/787006/galleries/2393602/o_240421081243_g0001.jpg")
  204. <?xml version="1.0" encoding="utf-8"?>
  205. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  206.     xmlns:tools="http://schemas.android.com/tools"
  207.     android:layout_width="match_parent"
  208.     android:layout_height="match_parent"
  209.     tools:context=".MainActivity"
  210.     android:orientation="vertical"
  211.     android:gravity="center">
  212.    <ImageView
  213.        android:id="@+id/imageView"
  214.        android:layout_height="match_parent"
  215.        android:layout_width="match_parent"
  216.        android:scaleType="centerCrop"
  217.        android:visibility="gone" />
  218.    <Button
  219.        android:id="@+id/btn_back"
  220.        android:layout_width="250dp"
  221.        android:layout_height="wrap_content"
  222.        android:text="加载图片"
  223.        android:textSize="40sp"/>
  224. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  225. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  226.     xmlns:tools="http://schemas.android.com/tools"
  227.     android:layout_width="match_parent"
  228.     android:layout_height="match_parent"
  229.     tools:context=".MainActivity"
  230.     android:orientation="vertical"
  231.     android:gravity="center">
  232.    <ImageView
  233.        android:id="@+id/imageView"
  234.        android:layout_height="match_parent"
  235.        android:layout_width="match_parent"
  236.        android:scaleType="centerCrop"
  237.        android:visibility="gone" />
  238.    <Button
  239.        android:id="@+id/btn_back"
  240.        android:layout_width="250dp"
  241.        android:layout_height="wrap_content"
  242.        android:text="加载图片"
  243.        android:textSize="40sp"/>
  244. </LinearLayout>}
  245. <?xml version="1.0" encoding="utf-8"?>
  246. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  247.     xmlns:tools="http://schemas.android.com/tools"
  248.     android:layout_width="match_parent"
  249.     android:layout_height="match_parent"
  250.     tools:context=".MainActivity"
  251.     android:orientation="vertical"
  252.     android:gravity="center">
  253.    <ImageView
  254.        android:id="@+id/imageView"
  255.        android:layout_height="match_parent"
  256.        android:layout_width="match_parent"
  257.        android:scaleType="centerCrop"
  258.        android:visibility="gone" />
  259.    <Button
  260.        android:id="@+id/btn_back"
  261.        android:layout_width="250dp"
  262.        android:layout_height="wrap_content"
  263.        android:text="加载图片"
  264.        android:textSize="40sp"/>
  265. </LinearLayout>  }
  266.     }
  267.     private suspend fun loadImageFromUrl(url: String) {
  268. <?xml version="1.0" encoding="utf-8"?>
  269. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  270.     xmlns:tools="http://schemas.android.com/tools"
  271.     android:layout_width="match_parent"
  272.     android:layout_height="match_parent"
  273.     tools:context=".MainActivity"
  274.     android:orientation="vertical"
  275.     android:gravity="center">
  276.    <ImageView
  277.        android:id="@+id/imageView"
  278.        android:layout_height="match_parent"
  279.        android:layout_width="match_parent"
  280.        android:scaleType="centerCrop"
  281.        android:visibility="gone" />
  282.    <Button
  283.        android:id="@+id/btn_back"
  284.        android:layout_width="250dp"
  285.        android:layout_height="wrap_content"
  286.        android:text="加载图片"
  287.        android:textSize="40sp"/>
  288. </LinearLayout>  val bitmap = Glide.with(this@MainActivity)
  289. <?xml version="1.0" encoding="utf-8"?>
  290. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  291.     xmlns:tools="http://schemas.android.com/tools"
  292.     android:layout_width="match_parent"
  293.     android:layout_height="match_parent"
  294.     tools:context=".MainActivity"
  295.     android:orientation="vertical"
  296.     android:gravity="center">
  297.    <ImageView
  298.        android:id="@+id/imageView"
  299.        android:layout_height="match_parent"
  300.        android:layout_width="match_parent"
  301.        android:scaleType="centerCrop"
  302.        android:visibility="gone" />
  303.    <Button
  304.        android:id="@+id/btn_back"
  305.        android:layout_width="250dp"
  306.        android:layout_height="wrap_content"
  307.        android:text="加载图片"
  308.        android:textSize="40sp"/>
  309. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  310. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  311.     xmlns:tools="http://schemas.android.com/tools"
  312.     android:layout_width="match_parent"
  313.     android:layout_height="match_parent"
  314.     tools:context=".MainActivity"
  315.     android:orientation="vertical"
  316.     android:gravity="center">
  317.    <ImageView
  318.        android:id="@+id/imageView"
  319.        android:layout_height="match_parent"
  320.        android:layout_width="match_parent"
  321.        android:scaleType="centerCrop"
  322.        android:visibility="gone" />
  323.    <Button
  324.        android:id="@+id/btn_back"
  325.        android:layout_width="250dp"
  326.        android:layout_height="wrap_content"
  327.        android:text="加载图片"
  328.        android:textSize="40sp"/>
  329. </LinearLayout>.asBitmap()
  330. <?xml version="1.0" encoding="utf-8"?>
  331. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  332.     xmlns:tools="http://schemas.android.com/tools"
  333.     android:layout_width="match_parent"
  334.     android:layout_height="match_parent"
  335.     tools:context=".MainActivity"
  336.     android:orientation="vertical"
  337.     android:gravity="center">
  338.    <ImageView
  339.        android:id="@+id/imageView"
  340.        android:layout_height="match_parent"
  341.        android:layout_width="match_parent"
  342.        android:scaleType="centerCrop"
  343.        android:visibility="gone" />
  344.    <Button
  345.        android:id="@+id/btn_back"
  346.        android:layout_width="250dp"
  347.        android:layout_height="wrap_content"
  348.        android:text="加载图片"
  349.        android:textSize="40sp"/>
  350. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  351. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  352.     xmlns:tools="http://schemas.android.com/tools"
  353.     android:layout_width="match_parent"
  354.     android:layout_height="match_parent"
  355.     tools:context=".MainActivity"
  356.     android:orientation="vertical"
  357.     android:gravity="center">
  358.    <ImageView
  359.        android:id="@+id/imageView"
  360.        android:layout_height="match_parent"
  361.        android:layout_width="match_parent"
  362.        android:scaleType="centerCrop"
  363.        android:visibility="gone" />
  364.    <Button
  365.        android:id="@+id/btn_back"
  366.        android:layout_width="250dp"
  367.        android:layout_height="wrap_content"
  368.        android:text="加载图片"
  369.        android:textSize="40sp"/>
  370. </LinearLayout>.load(url)
  371. <?xml version="1.0" encoding="utf-8"?>
  372. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  373.     xmlns:tools="http://schemas.android.com/tools"
  374.     android:layout_width="match_parent"
  375.     android:layout_height="match_parent"
  376.     tools:context=".MainActivity"
  377.     android:orientation="vertical"
  378.     android:gravity="center">
  379.    <ImageView
  380.        android:id="@+id/imageView"
  381.        android:layout_height="match_parent"
  382.        android:layout_width="match_parent"
  383.        android:scaleType="centerCrop"
  384.        android:visibility="gone" />
  385.    <Button
  386.        android:id="@+id/btn_back"
  387.        android:layout_width="250dp"
  388.        android:layout_height="wrap_content"
  389.        android:text="加载图片"
  390.        android:textSize="40sp"/>
  391. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  392. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  393.     xmlns:tools="http://schemas.android.com/tools"
  394.     android:layout_width="match_parent"
  395.     android:layout_height="match_parent"
  396.     tools:context=".MainActivity"
  397.     android:orientation="vertical"
  398.     android:gravity="center">
  399.    <ImageView
  400.        android:id="@+id/imageView"
  401.        android:layout_height="match_parent"
  402.        android:layout_width="match_parent"
  403.        android:scaleType="centerCrop"
  404.        android:visibility="gone" />
  405.    <Button
  406.        android:id="@+id/btn_back"
  407.        android:layout_width="250dp"
  408.        android:layout_height="wrap_content"
  409.        android:text="加载图片"
  410.        android:textSize="40sp"/>
  411. </LinearLayout>.submit()
  412. <?xml version="1.0" encoding="utf-8"?>
  413. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  414.     xmlns:tools="http://schemas.android.com/tools"
  415.     android:layout_width="match_parent"
  416.     android:layout_height="match_parent"
  417.     tools:context=".MainActivity"
  418.     android:orientation="vertical"
  419.     android:gravity="center">
  420.    <ImageView
  421.        android:id="@+id/imageView"
  422.        android:layout_height="match_parent"
  423.        android:layout_width="match_parent"
  424.        android:scaleType="centerCrop"
  425.        android:visibility="gone" />
  426.    <Button
  427.        android:id="@+id/btn_back"
  428.        android:layout_width="250dp"
  429.        android:layout_height="wrap_content"
  430.        android:text="加载图片"
  431.        android:textSize="40sp"/>
  432. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  433. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  434.     xmlns:tools="http://schemas.android.com/tools"
  435.     android:layout_width="match_parent"
  436.     android:layout_height="match_parent"
  437.     tools:context=".MainActivity"
  438.     android:orientation="vertical"
  439.     android:gravity="center">
  440.    <ImageView
  441.        android:id="@+id/imageView"
  442.        android:layout_height="match_parent"
  443.        android:layout_width="match_parent"
  444.        android:scaleType="centerCrop"
  445.        android:visibility="gone" />
  446.    <Button
  447.        android:id="@+id/btn_back"
  448.        android:layout_width="250dp"
  449.        android:layout_height="wrap_content"
  450.        android:text="加载图片"
  451.        android:textSize="40sp"/>
  452. </LinearLayout>.get()
  453. <?xml version="1.0" encoding="utf-8"?>
  454. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  455.     xmlns:tools="http://schemas.android.com/tools"
  456.     android:layout_width="match_parent"
  457.     android:layout_height="match_parent"
  458.     tools:context=".MainActivity"
  459.     android:orientation="vertical"
  460.     android:gravity="center">
  461.    <ImageView
  462.        android:id="@+id/imageView"
  463.        android:layout_height="match_parent"
  464.        android:layout_width="match_parent"
  465.        android:scaleType="centerCrop"
  466.        android:visibility="gone" />
  467.    <Button
  468.        android:id="@+id/btn_back"
  469.        android:layout_width="250dp"
  470.        android:layout_height="wrap_content"
  471.        android:text="加载图片"
  472.        android:textSize="40sp"/>
  473. </LinearLayout>  withContext(Dispatchers.Main) {
  474. <?xml version="1.0" encoding="utf-8"?>
  475. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  476.     xmlns:tools="http://schemas.android.com/tools"
  477.     android:layout_width="match_parent"
  478.     android:layout_height="match_parent"
  479.     tools:context=".MainActivity"
  480.     android:orientation="vertical"
  481.     android:gravity="center">
  482.    <ImageView
  483.        android:id="@+id/imageView"
  484.        android:layout_height="match_parent"
  485.        android:layout_width="match_parent"
  486.        android:scaleType="centerCrop"
  487.        android:visibility="gone" />
  488.    <Button
  489.        android:id="@+id/btn_back"
  490.        android:layout_width="250dp"
  491.        android:layout_height="wrap_content"
  492.        android:text="加载图片"
  493.        android:textSize="40sp"/>
  494. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  495. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  496.     xmlns:tools="http://schemas.android.com/tools"
  497.     android:layout_width="match_parent"
  498.     android:layout_height="match_parent"
  499.     tools:context=".MainActivity"
  500.     android:orientation="vertical"
  501.     android:gravity="center">
  502.    <ImageView
  503.        android:id="@+id/imageView"
  504.        android:layout_height="match_parent"
  505.        android:layout_width="match_parent"
  506.        android:scaleType="centerCrop"
  507.        android:visibility="gone" />
  508.    <Button
  509.        android:id="@+id/btn_back"
  510.        android:layout_width="250dp"
  511.        android:layout_height="wrap_content"
  512.        android:text="加载图片"
  513.        android:textSize="40sp"/>
  514. </LinearLayout>imageView.visibility = View.VISIBLE
  515. <?xml version="1.0" encoding="utf-8"?>
  516. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  517.     xmlns:tools="http://schemas.android.com/tools"
  518.     android:layout_width="match_parent"
  519.     android:layout_height="match_parent"
  520.     tools:context=".MainActivity"
  521.     android:orientation="vertical"
  522.     android:gravity="center">
  523.    <ImageView
  524.        android:id="@+id/imageView"
  525.        android:layout_height="match_parent"
  526.        android:layout_width="match_parent"
  527.        android:scaleType="centerCrop"
  528.        android:visibility="gone" />
  529.    <Button
  530.        android:id="@+id/btn_back"
  531.        android:layout_width="250dp"
  532.        android:layout_height="wrap_content"
  533.        android:text="加载图片"
  534.        android:textSize="40sp"/>
  535. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  536. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  537.     xmlns:tools="http://schemas.android.com/tools"
  538.     android:layout_width="match_parent"
  539.     android:layout_height="match_parent"
  540.     tools:context=".MainActivity"
  541.     android:orientation="vertical"
  542.     android:gravity="center">
  543.    <ImageView
  544.        android:id="@+id/imageView"
  545.        android:layout_height="match_parent"
  546.        android:layout_width="match_parent"
  547.        android:scaleType="centerCrop"
  548.        android:visibility="gone" />
  549.    <Button
  550.        android:id="@+id/btn_back"
  551.        android:layout_width="250dp"
  552.        android:layout_height="wrap_content"
  553.        android:text="加载图片"
  554.        android:textSize="40sp"/>
  555. </LinearLayout>button.visibility = View.GONE
  556. <?xml version="1.0" encoding="utf-8"?>
  557. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  558.     xmlns:tools="http://schemas.android.com/tools"
  559.     android:layout_width="match_parent"
  560.     android:layout_height="match_parent"
  561.     tools:context=".MainActivity"
  562.     android:orientation="vertical"
  563.     android:gravity="center">
  564.    <ImageView
  565.        android:id="@+id/imageView"
  566.        android:layout_height="match_parent"
  567.        android:layout_width="match_parent"
  568.        android:scaleType="centerCrop"
  569.        android:visibility="gone" />
  570.    <Button
  571.        android:id="@+id/btn_back"
  572.        android:layout_width="250dp"
  573.        android:layout_height="wrap_content"
  574.        android:text="加载图片"
  575.        android:textSize="40sp"/>
  576. </LinearLayout><?xml version="1.0" encoding="utf-8"?>
  577. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  578.     xmlns:tools="http://schemas.android.com/tools"
  579.     android:layout_width="match_parent"
  580.     android:layout_height="match_parent"
  581.     tools:context=".MainActivity"
  582.     android:orientation="vertical"
  583.     android:gravity="center">
  584.    <ImageView
  585.        android:id="@+id/imageView"
  586.        android:layout_height="match_parent"
  587.        android:layout_width="match_parent"
  588.        android:scaleType="centerCrop"
  589.        android:visibility="gone" />
  590.    <Button
  591.        android:id="@+id/btn_back"
  592.        android:layout_width="250dp"
  593.        android:layout_height="wrap_content"
  594.        android:text="加载图片"
  595.        android:textSize="40sp"/>
  596. </LinearLayout>imageView.setImageBitmap(bitmap)
  597. <?xml version="1.0" encoding="utf-8"?>
  598. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  599.     xmlns:tools="http://schemas.android.com/tools"
  600.     android:layout_width="match_parent"
  601.     android:layout_height="match_parent"
  602.     tools:context=".MainActivity"
  603.     android:orientation="vertical"
  604.     android:gravity="center">
  605.    <ImageView
  606.        android:id="@+id/imageView"
  607.        android:layout_height="match_parent"
  608.        android:layout_width="match_parent"
  609.        android:scaleType="centerCrop"
  610.        android:visibility="gone" />
  611.    <Button
  612.        android:id="@+id/btn_back"
  613.        android:layout_width="250dp"
  614.        android:layout_height="wrap_content"
  615.        android:text="加载图片"
  616.        android:textSize="40sp"/>
  617. </LinearLayout>  }
  618.     }
  619. }
复制代码
​    activity_main.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     tools:context=".MainActivity"
  7.     android:orientation="vertical"
  8.     android:gravity="center">
  9.    <ImageView
  10.        android:id="@+id/imageView"
  11.        android:layout_height="match_parent"
  12.        android:layout_width="match_parent"
  13.        android:scaleType="centerCrop"
  14.        android:visibility="gone" />
  15.    <Button
  16.        android:id="@+id/btn_back"
  17.        android:layout_width="250dp"
  18.        android:layout_height="wrap_content"
  19.        android:text="加载图片"
  20.        android:textSize="40sp"/>
  21. </LinearLayout>
复制代码
​    运行效果如下。

声明:本文转自【Kotlin】协程

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

渣渣兔

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表