Kotlin 协程Flow 流异常处理 ( 收集元素异常处理 | 使用 try...catch 代码块捕获处理异常 | 发射元素时异常处理 | 使用 Flow#catch 函数捕获处理异常 )

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 协程Flow 流异常处理 ( 收集元素异常处理 | 使用 try...catch 代码块捕获处理异常 | 发射元素时异常处理 | 使用 Flow#catch 函数捕获处理异常 )相关的知识,希望对你有一定的参考价值。

文章目录





一、Flow 流异常处理



Flow 流

  • 构建器代码 : flow , flowOf , asFlow ;
  • 发射元素 : emit 发射元素 ;
  • 收集元素 : collect 收集元素 ;
  • 各种运算符代码 : 过渡操作符 , 限长操作符 , 末端操作符 等 ;

中 , 如果运行时 , 抛出异常 , 可以使用

  • trycatch(e: Exception) 代码块 收集元素时捕获异常
  • Flow#catch 函数 发射元素时捕获异常

处理异常 ;





二、收集元素异常处理




1、收集元素异常代码示例


异常代码示例 : 如果收集的元素 it <= 1 , 则检查通过 , 否则当 it > 1 时 会报异常 ;

package kim.hsl.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking

class MainActivity : AppCompatActivity() 
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        runBlocking 
            flowEmit().collect 
                println("收集元素 $it")
                check(it <= 1) 
                    "抛出异常 $it <= 1"
                
            
        
    

    suspend fun flowEmit() = flow<Int> 
        // 以 100 ms 的间隔发射元素
        for (i in 0..5) 
            emit(i)
            println("发射元素 $i")
        
    

执行结果 :it > 1 时 会报异常 Caused by: java.lang.IllegalStateException: 抛出异常 2 <= 1 ;

21:51:03.014 System.out   kim.hsl.coroutine     I  收集元素 0
21:51:03.015 System.out   kim.hsl.coroutine     I  发射元素 0
21:51:03.015 System.out   kim.hsl.coroutine     I  收集元素 1
21:51:03.015 System.out   kim.hsl.coroutine     I  发射元素 1
21:51:03.015 System.out   kim.hsl.coroutine     I  收集元素 2
--------- beginning of crash
21:51:03.021 Andro...time kim.hsl.coroutine     D  Shutting down VM
21:51:03.030 Andro...time kim.hsl.coroutine     E  FATAL EXCEPTION: main
                                                   Process: kim.hsl.coroutine, PID: 6476
                                                   java.lang.RuntimeException: Unable to start activity ComponentInfokim.hsl.coroutine/kim.hsl.coroutine.MainActivity: java.lang.IllegalStateException: 抛出异常 2 <= 1
                                                   	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2951)
                                                   	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086)
                                                   	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
                                                   	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
                                                   	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
                                                   	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
                                                   	at android.os.Handler.dispatchMessage(Handler.java:106)
                                                   	at android.os.Looper.loop(Looper.java:193)
                                                   	at android.app.ActivityThread.main(ActivityThread.java:6718)
                                                   	at java.lang.reflect.Method.invoke(Native Method)
                                                   	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
                                                   	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
                                                   Caused by: java.lang.IllegalStateException: 抛出异常 2 <= 1
                                                   	at kim.hsl.coroutine.MainActivity$onCreate$1$invokeSuspend$$inlined$collect$1.emit(Collect.kt:134)
                                                   	at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
                                                   	at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
                                                   	at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:77)
                                                   	at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:59)
                                                   	at kim.hsl.coroutine.MainActivity$flowEmit$2.invokeSuspend(MainActivity.kt:27)
                                                   	at kim.hsl.coroutine.MainActivity$flowEmit$2.invoke(Unknown Source:8)
                                                   	at kim.hsl.coroutine.MainActivity$flowEmit$2.invoke(Unknown Source:4)
                                                   	at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:61)
                                                   	at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:212)
                                                   	at kim.hsl.coroutine.MainActivity$onCreate$1.invokeSuspend(MainActivity.kt:32)
                                                   	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                                                   	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
                                                   	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277)
                                                   	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:87)
                                                   	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:61)
                                                   	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
                                                   	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:40)
                                                   	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
                                                   	at kim.hsl.coroutine.MainActivity.onCreate(MainActivity.kt:14)
                                                   	at android.app.Activity.performCreate(Activity.java:7144)
                                                   	at android.app.Activity.performCreate(Activity.java:7135)
                                                   	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
                                                   	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2931)
                                                   	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086) 
                                                   	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
                                                   	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
                                                   	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
                                                   	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816) 
                                                   	at android.os.Handler.dispatchMessage(Handler.java:106) 
                                                   	at android.os.Looper.loop(Looper.java:193) 
                                                   	at android.app.ActivityThread.main(ActivityThread.java:6718) 
                                                   	at java.lang.reflect.Method.invoke(Native Method) 
                                                   	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
                                                   	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
21:51:03.066 Process      kim.hsl.coroutine     I  Sending signal. PID: 6476 SIG: 9
---------------------------- PROCESS ENDED (6476) for package kim.hsl.coroutine ----------------------------


2、收集元素捕获异常代码示例


代码示例 : 在 收集元素 时 , 使用 try…catch 代码块捕获异常 ;

package kim.hsl.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking

class MainActivity : AppCompatActivity() 
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        runBlocking 
            try 
                flowEmit().collect 
                    println("收集元素 $it")
                    check(it <= 1) 
                        "抛出异常 $it <= 1"
                    
                
             catch (e: Exception) 
                println("捕获到了异常 $e.message")
            
        
    

    suspend fun flowEmit() = flow<Int> 
        // 以 100 ms 的间隔发射元素
        for (i in 0..5) 
            emit(i)
            println("发射元素 $i")
        
    

执行结果 :

21:57:22.932 System.out   kim.hsl.coroutine     I  收集元素 0
21:57:22.932 System.out   kim.hsl.coroutine     I  发射元素 0
21:57:22.933 System.out   kim.hsl.coroutine     I  收集元素 1
21:57:22.933 System.out   kim.hsl.coroutine     I  发射元素 1
21:57:22.933 System.out   kim.hsl.coroutine     I  收集元素 2
21:57:22.934 System.out   kim.hsl.coroutine     I  捕获到了异常 抛出异常 2 <= 1





三、发射元素异常处理




1、发射元素异常代码示例


代码示例 :

package kim.hsl.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.runBlocking
import java.io.IOException

class MainActivity : AppCompatActivity() 
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        runBlocking 
            flowEmit().collect 
                println("收集元素 $it")
            
        
    

    suspend fun flowEmit() = flow<Int> 
        emit(0)
        throw IOException("IO 异常")
    .flowOn(Dispatchers.IO)

执行结果 :

22:19:59.361 System.out   kim.hsl.coroutine     I  收集元素 0
22:19:59.368 Andro...time kim.hsl.coroutine     D  Shutting down VM
22:19:59.374 Andro...time kim.hsl.coroutine     E  FATAL EXCEPTION: main
                                                   Process: kim.hsl.coroutine, PID: 11490
                                                   java.lang.RuntimeException: Unable to start activity ComponentInfokim.hsl.coroutine/kim.hsl.coroutine.MainActivity: java.io.IOException: IO 异常
                                                   	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2951)
                                                   	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086)
                                                   	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
                                                   	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
                                                   	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
                                                   	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
                                                   	at android.os.Handler.dispatchMessage(Handler.java:106)
                                                   	at android.os.Looper.loop(Looper.java:以上是关于Kotlin 协程Flow 流异常处理 ( 收集元素异常处理 | 使用 try...catch 代码块捕获处理异常 | 发射元素时异常处理 | 使用 Flow#catch 函数捕获处理异常 )的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 协程Flow 异步流 ⑥ ( 调用 Flow#launchIn 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )

Kotlin 协程Flow 异步流 ⑥ ( 调用 Flow#launchIn 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )

Kotlin 协程Flow 流收尾工作 ( finally 代码块收尾 | onCompletion 代码块收尾 | onCompletion 中获取异常信息 | catch 代码块中捕获异常 )

Kotlin 协程Flow 流收尾工作 ( finally 代码块收尾 | onCompletion 代码块收尾 | onCompletion 中获取异常信息 | catch 代码块中捕获异常 )

Kotlin 协程Flow 异步流 ③ ( 冷流 | 流被收集时运行 | 流的连续性 )

Kotlin 协程Flow 异步流 ③ ( 冷流 | 流被收集时运行 | 流的连续性 )