• 【Kotlin 协程】协程简介 ( 协程概念 | 协程作用 | 创建 Android 工程并进行协程相关配置开发 | 异步任务与协程对比 )






    一、协程概念



    协程 Coroutine Kotlin 语言 中新出现的概念 , 在 Java 语言中没有 ;

    协程 是 基于 线程 的 , 是 轻量级 线程 ;





    二、协程作用



    协程主要作用如下 :

    • 处理耗时任务 : 耗时任务 通常需要 阻塞主线程 , 线程量级太重 , 耗时任务 推荐在协程中执行 ;
    • 保证主线程安全 : 从主线程中 安全地调用可能会挂起的函数 ;

    异步任务 AsyncTask 也可以处理耗时操作 , 避免耗时任务阻塞线程 , 但是在 Android 11 中 , 官方规定 该 api 已过时 , 被标记为弃用状态 , 建议使用

    • 协程
    • java.util.concurrent 包下的 Executor,ThreadPoolExecutor,FutureTask

    取代 AsyncTask ;





    三、创建 Android 工程并进行协程相关配置




    1、创建 Android 工程


    创建 Android 工程 , 在 Android Studio 中 选择 " 菜单栏 | File | New | New Project " 选项 , 创建工程 ,

    在这里插入图片描述

    创建 Empty Activity ;

    在这里插入图片描述

    注意选择 Kotlin 语言 , Android Studio 会自动添加 Kotlin 语言支持 ;

    在这里插入图片描述


    2、配置协程环境


    AndroidManifest.xml 清单文件 中 , 添加网络权限 :

    <uses-permission android:name="android.permission.INTERNET"/>
    
    • 1

    Android 中访问网络 , 建议使用 https 协议 , 如果在 Android 中使用 http 协议 , 则需要加入如下网络声明 : 在 res/xml 目录下 , 配置 network_security_config.xml 配置文件 ;

    
    <network-security-config>
        <base-config cleartextTrafficPermitted="true" />
    network-security-config>
    
    • 1
    • 2
    • 3
    • 4

    然后在 清单文件中的 application 节点 配置 如下属性 :

    android:networkSecurityConfig="@xml/network_security_config"
    
    • 1

    完整的清单文件配置示例 :

    
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="kim.hsl.coroutine">
        <uses-permission android:name="android.permission.INTERNET"/>
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.Coroutine"
            android:networkSecurityConfig="@xml/network_security_config">
            <activity android:name=".MainActivity"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                intent-filter>
            activity>
        application>
    manifest>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在 build.gradle 中设置协程依赖 :

    dependencies {
        implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC-native-mt'
        implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC-native-mt'
    }
    
    • 1
    • 2
    • 3
    • 4

    3、布局文件


    布局文件 :

    
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <Button
            android:id="@+id/asyncTaskButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="异步任务方法"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.2"
            app:layout_constraintHorizontal_bias="0.5"/>
    
        <Button
            android:id="@+id/coroutineButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="协程方法"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.4"
            app:layout_constraintHorizontal_bias="0.5"/>
    
    androidx.constraintlayout.widget.ConstraintLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    4、异步任务代码示例


            findViewById<Button>(R.id.asyncTaskButton).also {
                it.setOnClickListener {
                    // 使用异步任务执行耗时操作,
                    // 使用匿名内部类形式定义异步任务 ,
                    // Java 匿名内部类 对应 Kotlin 对象表达式
                    object : AsyncTask<Void, Void, Void>(){
                        override fun doInBackground(vararg params: Void?): Void? {
                            // 在子线程执行任务
                            Log.i("MainActivity", "doInBackground : 子线程执行异步任务执行耗时操作")
                            return null
                        }
    
                        override fun onPostExecute(result: Void?) {
                            super.onPostExecute(result)
                            // 主线程更新 UI
                            Log.i("MainActivity", "onPostExecute : 主线程更新 UI")
                        }
                    }.execute()
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5、协程代码示例


            findViewById<Button>(R.id.coroutineButton).also {
                it.setOnClickListener {
                    // 创建协程
                    GlobalScope.launch {
                        // Dispatchers.IO 是协程任务调度器, 用于执行耗时操作
                        withContext(Dispatchers.IO){
                            Log.i("MainActivity", "withContext : 协程中执行耗时操作")
                        }
                        // 主线程更新 UI
                        Log.i("MainActivity", "GlobalScope : 主线程更新 UI")
                    }
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6、完整代码示例


    package kim.hsl.coroutine
    
    import android.os.AsyncTask
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.util.Log
    import android.widget.Button
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.GlobalScope
    import kotlinx.coroutines.launch
    import kotlinx.coroutines.withContext
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            findViewById<Button>(R.id.asyncTaskButton).also {
                it.setOnClickListener {
                    // 使用异步任务执行耗时操作,
                    // 使用匿名内部类形式定义异步任务 ,
                    // Java 匿名内部类 对应 Kotlin 对象表达式
                    object : AsyncTask<Void, Void, Void>(){
                        override fun doInBackground(vararg params: Void?): Void? {
                            // 在子线程执行任务
                            Log.i("MainActivity", "doInBackground : 子线程执行异步任务执行耗时操作")
                            return null
                        }
    
                        override fun onPostExecute(result: Void?) {
                            super.onPostExecute(result)
                            // 主线程更新 UI
                            Log.i("MainActivity", "onPostExecute : 主线程更新 UI")
                        }
                    }.execute()
                }
            }
    
            findViewById<Button>(R.id.coroutineButton).also {
                it.setOnClickListener {
                    // 创建协程
                    GlobalScope.launch {
                        // Dispatchers.IO 是协程任务调度器, 用于执行耗时操作
                        withContext(Dispatchers.IO){
                            Log.i("MainActivity", "withContext : 协程中执行耗时操作")
                        }
                        // 主线程更新 UI
                        Log.i("MainActivity", "GlobalScope : 主线程更新 UI")
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53




    四、异步任务与协程对比



    异步任务与协程对比 :

    • 相同点 : 都可以 处理耗时任务 , 保证主线程的安全性 ;
    • 异步任务缺陷 : 不符合人类的思维逻辑 , 其先执行 doInBackground 方法在其中执行后台任务 , 然后再通过回调触发 onPostExecute 方法在主线程执行操作 ;
    • 协程优点 : 符合人类思维习惯 , 借助编辑器实现了 异步任务同步化 , 没有回调操作 ; 可以在执行一段程序后 挂起 , 之后在挂起的地方 恢复执行 ;
  • 相关阅读:
    Web前端基础知识
    压缩状态DP位运算
    《算法导论》第17章-摊还分析 17.1 聚合分析 && 17.2 核算法&&17.3 势能法
    Fastdfs之集群安装
    Linux下ElasticSearch7.9.2安装配置(包含服务器配置、启动停止脚本、开放端口和elasticsearch-head插件的使用)
    Day6:无序二叉树的插入以及遍历(前/中/后序)
    qtdesigner的一些实用设置
    【源码解析】Spring源码解读-bean的加载
    1470. Shuffle the Array
    [UDS] --- UDS服务应该支持的NRC
  • 原文地址:https://blog.csdn.net/han1202012/article/details/127991876