diff --git a/Tutorial1-1CoroutinesBasics/build.gradle b/Tutorial1-1CoroutinesBasics/build.gradle index 8de4f2b..4e0eb8f 100644 --- a/Tutorial1-1CoroutinesBasics/build.gradle +++ b/Tutorial1-1CoroutinesBasics/build.gradle @@ -161,4 +161,5 @@ dependencies { // Espresso androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0" } diff --git a/Tutorial1-1CoroutinesBasics/src/main/AndroidManifest.xml b/Tutorial1-1CoroutinesBasics/src/main/AndroidManifest.xml index 6733888..566b744 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/AndroidManifest.xml +++ b/Tutorial1-1CoroutinesBasics/src/main/AndroidManifest.xml @@ -2,7 +2,7 @@ - + + diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/MainActivity.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/MainActivity.kt index 9560aea..60a1def 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/MainActivity.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/MainActivity.kt @@ -14,6 +14,7 @@ import com.smarttoolfactory.tutorial1_1coroutinesbasics.adapter.ChapterSelection import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter1_basics.Activity1Basics import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter2_scopes.Activity2CoroutineScope import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter3_lifecycle.Activity3CoroutineLifecycle +import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter3_lifecycle.Activity3LifecycleScope import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter4_supervisorjob.Activity4SupervisorJob import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter5_viewmodel.Activity5ViewModelRxJava import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter5_viewmodel.Activity5ViewModelScope @@ -42,6 +43,7 @@ class MainActivity : AppCompatActivity(), BaseAdapter.OnRecyclerViewItemClickLis activityClassModels.add(ActivityClassModel(Activity1Basics::class.java)) activityClassModels.add(ActivityClassModel(Activity2CoroutineScope::class.java)) activityClassModels.add(ActivityClassModel(Activity3CoroutineLifecycle::class.java)) + activityClassModels.add(ActivityClassModel(Activity3LifecycleScope::class.java)) activityClassModels.add(ActivityClassModel(Activity4SupervisorJob::class.java)) activityClassModels.add(ActivityClassModel(Activity5ViewModelScope::class.java)) activityClassModels.add(ActivityClassModel(Activity5ViewModelRxJava::class.java)) diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter3_lifecycle/Activity3LifecycleScope.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter3_lifecycle/Activity3LifecycleScope.kt new file mode 100644 index 0000000..df94281 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter3_lifecycle/Activity3LifecycleScope.kt @@ -0,0 +1,88 @@ +package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter3_lifecycle + +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope +import com.smarttoolfactory.tutorial1_1basics.R +import com.smarttoolfactory.tutorial1_1basics.databinding.Activity3LifecycleScopeBinding +import com.smarttoolfactory.tutorial1_1coroutinesbasics.util.dataBinding +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +/* + lifecycleScope.launch{} is an alternatie to Handler().postDelayed() + + activity.lifecycleScope.launch { + // scope bound to Activity Lifecycle + } + fragment.lifecycleScope.launch { + // scope bound to Fragment Lifecycle + } + fragment.viewLifecycleOwner.launch{ + // scope bound to Fragment View + } + + Be aware that lifecycleScope is convenient when dealing with UI events like, for example, showing a tip for the user and hiding it after a small delay. + lifecycleScope.launch { + delay(5000) + showTip() + delay(5000) + hideTip() + } + + Without using Coroutines and lifecycleScope, this would be: + val DELAY = 5000 + Handler().postDelayed({ + showTip() + Handler().postDelayed({ + hideTip() + }, DELAY) + }, DELAY) + + LifecycleScope is bound to Dispatcher.Main. That means if you don’t change Dispatcher explicitly all the coroutines inside LifecycleScope will be executed on the main thread. + + https://medium.com/corouteam/exploring-kotlin-coroutines-and-lifecycle-architectural-components-integration-on-android-c63bb8a9156f + https://android.jlelse.eu/coroutine-in-android-working-with-lifecycle-fc9c1a31e5f3 + https://kotlin.christmas/2019/13 +* */ + +class Activity3LifecycleScope : AppCompatActivity(R.layout.activity3_lifecycle_scope) { + + private val binding: Activity3LifecycleScopeBinding by dataBinding() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val builder = AlertDialog.Builder(this) + builder.setMessage("Mesajj") + builder.setTitle("Titlee") + val alertDialog = builder.create() + + + binding.button1.setOnClickListener { + binding.textViewResult.text = binding.textViewResult.text.toString() + "Clicked\n" + lifecycleScope.launch { + + binding.textViewResult.text = + binding.textViewResult.text.toString() + "πŸ€“ Delay 5 sn before showing dialog\n" + delay(5000) + + alertDialog.show() + + binding.textViewResult.text = + binding.textViewResult.text.toString() + "πŸ₯³ Delay 5 sn after showing dialog\n" + delay(5000) + + binding.textViewResult.text = + binding.textViewResult.text.toString() + "Dismissed AlertDialog \n" + Toast.makeText(baseContext, "Dismissed AlertDialog", Toast.LENGTH_SHORT).show() + alertDialog.dismiss() + } + binding.textViewResult.text = + binding.textViewResult.text.toString() + "πŸš—πŸš—πŸš— Codes after lifecycleScope \n" + } + + } +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter5_viewmodel/CoroutinesViewModel.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter5_viewmodel/CoroutinesViewModel.kt index 16d8fd1..a447791 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter5_viewmodel/CoroutinesViewModel.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter5_viewmodel/CoroutinesViewModel.kt @@ -44,24 +44,24 @@ class CoroutinesViewModel(private val viewModelDispatcher: CoroutineDispatcher) fun getMockResult(timeMillis: Long = 2000) { - println("getMockResult() loading...") + println("1 - getMockResult() loading...") result.value = "Loading..." enableResultButton.value = false viewModelScope.launch { - println("πŸ™„ getMockResult() START ViewModel scope: $this, thread: ${Thread.currentThread().name}") + println("πŸ™„ 2 - getMockResult() START ViewModel scope: $this, thread: ${Thread.currentThread().name}") - result.value = generateMockNetworkResponseOrThrowException(timeMillis) + result.value = generateMockNetworkResponseOrThrowException(timeMillis) // 4 enableResultButton.value = true - println("getMockResult() ViewModel scope AFTER generateMockNetworkResponse() ${result.value}") + println("5 - getMockResult() ViewModel scope AFTER generateMockNetworkResponse() ${result.value}") } - println("getMockResult() END OF FUN") + println("3 - getMockResult() END OF FUN") - /* + /* 1 2 4 3 5 Prints: I: getMockResult() loading... I: πŸ™„ getMockResult() ViewModel scope: StandaloneCoroutine{Active}@ef7c60d, thread: main @@ -72,55 +72,45 @@ class CoroutinesViewModel(private val viewModelDispatcher: CoroutineDispatcher) } - - /** - * This method is for Unit-Testing exceptions + /* + Mock Response Functions */ - @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - fun throwExceptionInAScope(coroutineContext: CoroutineContext) { - - println("getMockResult() loading...") - // πŸ”₯πŸ”₯ - viewModelScope.launch(coroutineContext) { - - println("πŸ™„ getMockResult() START ViewModel scope: $this, thread: ${Thread.currentThread().name}") - - delay(2000) - throw RuntimeException("Exception Occurred") + private suspend fun generateMockNetworkResponseOrThrowException(timeMillis: Long = 2000): String { - } + println("πŸ₯Ά 4 - generateMockNetworkResponse() thread: ${Thread.currentThread().name}") - println("getMockResult() END OF FUN") + delay(timeMillis) + if (timeMillis > 2000) throw RuntimeException("Threw Network Exception") + return "Hello World" } - fun getMockResultFromDispatcherThread(timeMillis: Long) { - println("getMockResult() loading...") + println("1 - getMockResult() loading...") result.value = "Loading..." enableResultButton.value = false viewModelScope.launch(Dispatchers.Default) { - println("πŸ™„ getMockResult() ViewModel scope: $this, thread: ${Thread.currentThread().name}") + println("πŸ™„ 3 - getMockResult() ViewModel scope: $this, thread: ${Thread.currentThread().name}") withContext(Dispatchers.Main) { - result.value = generateMockNetworkResponseOrThrowException(timeMillis) + result.value = generateMockNetworkResponseOrThrowException(timeMillis) // 4 enableResultButton.value = true } - println("getMockResult() ViewModel scope AFTER") + println("5 - getMockResult() ViewModel scope AFTER") } - println("getMockResult() END OF FUN") + println("2 - getMockResult() END OF FUN") /* - Prints: + Prints: 1 3 2 4 5 or 1 2 3 4 5 */ @@ -155,9 +145,9 @@ class CoroutinesViewModel(private val viewModelDispatcher: CoroutineDispatcher) // longer than 2000 ms resultWithTimeout.value = generateMockNetworkResponseOrThrowException() } catch (exception: TimeoutCancellationException) { - resultWithTimeout.value = exception.message + resultWithTimeout.value = "1 - " + exception.message } catch (exception: Exception) { - resultWithTimeout.value = exception.message + resultWithTimeout.value = "2 - " + exception.message } } @@ -283,21 +273,6 @@ class CoroutinesViewModel(private val viewModelDispatcher: CoroutineDispatcher) } - /* - Mock Response Functions - */ - - private suspend fun generateMockNetworkResponseOrThrowException(timeMillis: Long = 2000): String { - - println("πŸ₯Ά generateMockNetworkResponse() thread: ${Thread.currentThread().name}") - - delay(timeMillis) - - if (timeMillis > 2000) throw RuntimeException("Threw Network Exception") - - return "Hello World" - } - private suspend fun generateRandomCity(): String { val cityList = listOf("Berlin", "New York", "London", "Paris", "Istanbul") @@ -317,6 +292,27 @@ class CoroutinesViewModel(private val viewModelDispatcher: CoroutineDispatcher) } + /** + * This method is for Unit-Testing exceptions + */ + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + fun throwExceptionInAScope(coroutineContext: CoroutineContext) { + + println("getMockResult() loading...") + + // πŸ”₯πŸ”₯ + viewModelScope.launch(coroutineContext) { + + println("πŸ™„ getMockResult() START ViewModel scope: $this, thread: ${Thread.currentThread().name}") + + delay(2000) + throw RuntimeException("Exception Occurred") + + } + + println("getMockResult() END OF FUN") + + } } class CoroutinesViewModelFactory : diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-1.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-1.kt new file mode 100644 index 0000000..11dc195 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-1.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from channels.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking + +/* +Rendezvous channel example +*/ + + +fun main() = runBlocking { + val channel = Channel() + + launch { + println("Sending A1") + channel.send("A1") + println("Sending A2") + channel.send("A2") + println("A done") + } + + launch { + println("Sending B1") + channel.send("B1") + println("B done") + } + + launch { + repeat(3) { + println("Calling receive()") + val x = channel.receive() + println("receive is done $x") + } + } + + println("Done!") +} + +/* +* Output : + +Done! +Sending A1 +Sending B1 +Calling receive() +receive is done A1 +Calling receive() +receive is done B1 +Calling receive() +Sending A2 +A done +B done +receive is done A2 + +* */ \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-01.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-2.kt similarity index 67% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-01.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-2.kt index ef61b44..fb8e286 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-01.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-2.kt @@ -6,16 +6,26 @@ package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -fun main() = runBlocking { +fun main() = runBlocking { // coroutine 1 + val channel = Channel() - launch { + launch { // coroutine 2 // this might be heavy CPU-consuming computation or async logic, we'll just send five squares - for (x in 1..5) channel.send(x * x) + for (x in 1..5) { + println("send $x ") + channel.send(x * x) + } + } // here we print five received integers: - repeat(5) { println(channel.receive()) } + repeat(5) { + delay(3000) + println(channel.receive()) + } println("Done!") } + diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-02.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-3.kt similarity index 75% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-02.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-3.kt index 04295b2..c526e45 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-02.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-3.kt @@ -10,12 +10,20 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking fun main() = runBlocking { + val channel = Channel() launch { - for (x in 1..5) channel.send(x * x) + for (x in 1..5) + channel.send(x * x) channel.close() // we're done sending } + // here we print received values using `for` loop (until the channel is closed) + // 1st way of receiving data from channel for (y in channel) println(y) + // 2nd way of receiving data from channel + /*repeat(5) { + println(channel.receive()) }*/ + println("Done!") } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-03.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-4.kt similarity index 54% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-03.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-4.kt index cecd898..d64be72 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-03.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-4.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.channels.produce +import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking fun CoroutineScope.produceSquares(): ReceiveChannel = produce { @@ -16,7 +17,29 @@ fun CoroutineScope.produceSquares(): ReceiveChannel = produce { } fun main() = runBlocking { + + // 1st way of sending integers to the channel. + /*val squares = Channel() + launch { + for (x in 1..5) + squares.send(x * x) + squares.close() // we're done sending + }*/ + // 2nd way of sending integers to the channel. val squares = produceSquares() - squares.consumeEach { println(it) } + + + // 1st way of receiving integers from the channel. + squares.consumeEach { + delay(3000) + println(it) + } + // 2nd way of receiving integers from the channel. + /*repeat(5) { + delay(3000) + println(squares.receive()) + }*/ + println("Done!") } + diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-01.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-01.kt deleted file mode 100644 index f16abf6..0000000 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-01.kt +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -// This file was automatically generated from flow.md by Knit tool. Do not edit. -package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground - -fun foo(): List = listOf(1, 2, 3) - -fun main() { - foo().forEach { value -> println(value) } -} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-02.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-02.kt deleted file mode 100644 index 1f1b252..0000000 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-02.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -// This file was automatically generated from flow.md by Knit tool. Do not edit. -package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground - -fun foo2(): Sequence = sequence { // sequence builder - for (i in 1..3) { - Thread.sleep(100) // pretend we are computing it - yield(i) // yield next value - } -} - -fun main() { - foo2().forEach { value -> println(value) } -} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-1.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-1.kt new file mode 100644 index 0000000..396e309 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-1.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +fun main() { + + withoutSequence() + + withSequence() +} + +private fun withoutSequence() { + val result = listOf("a", "b", "ac", "d", "e", "f", "g", "h", "i", "j", "ak") + .filter { + println("filter: $it") + it.startsWith("a", ignoreCase = true) + } + .map { + println("map: $it") + it.toUpperCase() + } + .take(2) + .toList() + + println("size: ${result.size}") +} + +private fun withSequence() { + val result = listOf("a", "b", "ac", "d", "e", "f", "g", "h", "i", "j", "ak") + .asSequence() + .filter { + println("filter: $it") + it.startsWith("a", ignoreCase = true) + } + .map { + println("map: $it") + it.toUpperCase() + } + .take(2) + .toList() + + println("size: ${result.size}") +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-09.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10a.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-09.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10a.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10b.kt similarity index 93% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10b.kt index 1ff63b0..fa3cf48 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10b.kt @@ -17,6 +17,8 @@ fun numbers(): Flow = flow { emit(2) println("This line will not execute") emit(3) + } catch (ex: Exception) { + println(ex.message) } finally { println("Finally in numbers") } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-11.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-11.kt index 27af486..2d8e3d4 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-11.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-11.kt @@ -11,8 +11,20 @@ import kotlinx.coroutines.flow.reduce import kotlinx.coroutines.runBlocking fun main() = runBlocking { - val sum = (1..5).asFlow() + val sum1 = (1..5).asFlow() + .reduce { a, b -> + println("$a + $b = ${a + b}") + a + b + } // sum them (terminal operator) + println(sum1) + + println("----") + + val sum2 = (1..5).asFlow() .map { it * it } // squares of numbers from 1 to 5 - .reduce { a, b -> a + b } // sum them (terminal operator) - println(sum) + .reduce { a, b -> + println("$a + $b = ${a + b}") + a + b + } // sum them (terminal operator) + println(sum2) } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-13.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-13.kt index 3715cb6..86e375d 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-13.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-13.kt @@ -13,12 +13,12 @@ import kotlinx.coroutines.runBlocking fun log13(msg: String) = println("[${Thread.currentThread().name}] $msg") fun foo13(): Flow = flow { - log13("Started foo flow") for (i in 1..3) { emit(i) } } fun main() = runBlocking { + log13("Started foo flow") foo13().collect { value -> log13("Collected $value") } } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-15.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-15-flowOn.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-15.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-15-flowOn.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-18.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-1-without-buffer.kt similarity index 60% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-18.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-1-without-buffer.kt index 8898ddd..f81ca1b 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-18.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-1-without-buffer.kt @@ -8,25 +8,26 @@ package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking import kotlin.system.measureTimeMillis -fun foo18(): Flow = flow { +fun foo17_3(): Flow = flow { for (i in 1..3) { - delay(100) // pretend we are asynchronously waiting 100 ms + println("- value : $i - inside flow. delaying 1 second") + delay(1000) // pretend we are asynchronously waiting 100 ms + println("- value : $i - inside flow. Emitting") emit(i) // emit next value } } fun main() = runBlocking { val time = measureTimeMillis { - foo18() - .conflate() // conflate emissions, don't process each one + foo17_3() .collect { value -> - delay(300) // pretend we are processing it for 300 ms - println(value) + println("- value : $value - inside collect. delaying 5 second") + delay(5000) // pretend we are processing it for 300 ms + println("- value : $value - inside collect. completed") } } println("Collected in $time ms") diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-2-buffer.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-2-buffer.kt new file mode 100644 index 0000000..1e4c991 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-2-buffer.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.buffer +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.runBlocking +import kotlin.system.measureTimeMillis + +fun foo17_2(): Flow = flow { + for (i in 1..3) { + println("- value : $i - inside flow. delaying 1 second") + delay(1000) // pretend we are asynchronously waiting 100 ms + println("- value : $i - inside flow. Emitting") + emit(i) // emit next value + } +} + +fun main() = runBlocking { + val time = measureTimeMillis { + foo17_2() + .buffer() // buffer emissions, don't wait + .collect { value -> + println("- value : $value - inside collect. delaying 5 second") + delay(5000) // pretend we are processing it for 300 ms + println("- value : $value - inside collect. completed") + } + } + println("Collected in $time ms") +} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-3-buffer.kt similarity index 94% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-3-buffer.kt index 0941415..bec44b7 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-3-buffer.kt @@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking import kotlin.system.measureTimeMillis -fun foo17(): Flow = flow { +fun foo17_1(): Flow = flow { for (i in 1..3) { delay(100) // pretend we are asynchronously waiting 100 ms emit(i) // emit next value @@ -22,7 +22,7 @@ fun foo17(): Flow = flow { fun main() = runBlocking { val time = measureTimeMillis { - foo17() + foo17_1() .buffer() // buffer emissions, don't wait .collect { value -> delay(300) // pretend we are processing it for 300 ms diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-18-conflate.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-18-conflate.kt new file mode 100644 index 0000000..baeda7b --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-18-conflate.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.runBlocking +import kotlin.system.measureTimeMillis + +/* + +fun foo18(): Flow = flow { + for (i in 1..3) { + delay(100) // pretend we are asynchronously waiting 100 ms + emit(i) // emit next value + } +} + +fun main() = runBlocking { + val time = measureTimeMillis { + foo18() + .conflate() // conflate emissions, don't process each one + .collect { value -> + delay(300) // pretend we are processing it for 300 ms + println(value) + } + } + println("Collected in $time ms") +} +*/ + + +fun foo18(): Flow = flow { + for (i in 1..3) { + println("- value : $i - inside flow. delaying 1 second") + delay(1000) // pretend we are asynchronously waiting 100 ms + println("- value : $i - inside flow. Emitting") + emit(i) // emit next value + } +} + +fun main() = runBlocking { + val time = measureTimeMillis { + foo18() + .conflate() // conflate emissions, don't process each one. + .collect { value -> + println("- value : $value - inside collect. delaying 5 second") + delay(5000) // pretend we are processing it for 300 ms + println("- value : $value - inside collect. completed") + } + } + println("Collected in $time ms") +} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-19.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-19-collectLatest.kt similarity index 61% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-19.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-19-collectLatest.kt index 378dea2..f2292c3 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-19.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-19-collectLatest.kt @@ -12,9 +12,12 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking import kotlin.system.measureTimeMillis + fun foo19(): Flow = flow { for (i in 1..3) { - delay(100) // pretend we are asynchronously waiting 100 ms + println("- value : $i - inside flow. delaying 1 second") + delay(1000) // pretend we are asynchronously waiting 100 ms + println("- value : $i - inside flow. Emitting") emit(i) // emit next value } } @@ -22,10 +25,10 @@ fun foo19(): Flow = flow { fun main() = runBlocking { val time = measureTimeMillis { foo19() - .collectLatest { value -> // cancel & restart on the latest value - println("Collecting $value") - delay(300) // pretend we are processing it for 300 ms - println("Done $value") + .collectLatest { value -> + println("- value : $value - inside collect. delaying 5 second") + delay(5000) // pretend we are processing it for 300 ms + println("- value : $value - inside collect. completed") } } println("Collected in $time ms") diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-2.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-2.kt new file mode 100644 index 0000000..44f59b4 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-2.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +fun main() { + + val seqFromChunks = sequence { + yield(1) + println("test 1") + yieldAll((2..5).toList()) + println("test 2") // this line and the below lines is not executed. + yield(6) + + yieldAll(listOf(7, 8, 9)) + yieldAll(generateSequence(10) { it + 2 }) + } + + println(seqFromChunks.take(5).toList()) + + println("---------------------------------") + + val seqFromChunks2 = sequence { + yield(1) + println("test 1") + yieldAll((2..5).toList()) + println("test 2") + yield(6) + + yieldAll(listOf(7, 8, 9)) + println("test 3") + yieldAll(generateSequence(10) { it + 2 }) + println("test 4") // this line is not executed. + } + + println(seqFromChunks2.take(10).toList()) +} + diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-onEach.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-onEach.kt new file mode 100644 index 0000000..218dea2 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-onEach.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.runBlocking + +fun foo20(): Flow = flow { + for (i in 1..3) { + delay(1000) + emit(i) + } +} + +fun main() = runBlocking { + + val numbersFlow = (1..3).asFlow().onEach { delay(1000) } // flow of numbers 1,2,3 + + numbersFlow + .collect { + println(it) + } +} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-zip.kt similarity index 61% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-zip.kt index 4299cb7..52fac2c 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-zip.kt @@ -12,8 +12,14 @@ import kotlinx.coroutines.flow.zip import kotlinx.coroutines.runBlocking fun main() = runBlocking { - val nums = (1..3).asFlow() // numbers 1..3 - val strs = flowOf("one", "two", "three") // strings - nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string - .collect { println(it) } // collect and print + + val numbersFlow = (1..3).asFlow() // flow of numbers 1,2,3 + val stringsFlow = flowOf("one", "two", "three") // flow of strings + + numbersFlow.zip(stringsFlow) { a, b -> + "$a -> $b" + } // compose a single string + .collect { + println(it) + } // collect and print } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-21.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-21-zip.kt similarity index 65% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-21.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-21-zip.kt index 94a1ccb..81fcbc7 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-21.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-21-zip.kt @@ -10,10 +10,22 @@ import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking fun main() = runBlocking { - val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms - val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms + val nums = (1..3).asFlow().onEach { + println("1st flow. value : $it") + delay(100) + } // numbers 1..3 every 100 ms + val strs = flowOf("one", "two", "three").onEach { + println("2nd flow. value : $it") + delay(4000) + } // strings every 4000 ms + val startTime = System.currentTimeMillis() // remember the start time + nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string with "zip" + .map { + println("Applying map for : $it") + it + } .collect { value -> // collect and print println("$value at ${System.currentTimeMillis() - startTime} ms from start") } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-1.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-1.kt new file mode 100644 index 0000000..ae0e819 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-1.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.runBlocking + +fun main() = runBlocking { + val nums = (1..3).asFlow().onEach { + println("1st flow. value : $it") + delay(100) + } // numbers 1..3 every 300 ms + val strs = flowOf("one", "two", "three").onEach { + println("2nd flow. value : $it") + delay(4000) + } // strings every 400 ms + val startTime = System.currentTimeMillis() // remember the start time + + nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine" + .collect { value -> // collect and print + println("$value at ${System.currentTimeMillis() - startTime} ms from start") + } +} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-2.kt similarity index 90% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-2.kt index 44eb6f2..1ea4a4b 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-2.kt @@ -5,16 +5,17 @@ // This file was automatically generated from flow.md by Knit tool. Do not edit. package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking fun main() = runBlocking { val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms - val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms + val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms val startTime = System.currentTimeMillis() // remember the start time nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine" - .collect { value -> // collect and print + .collect { value -> // collect and print println("$value at ${System.currentTimeMillis() - startTime} ms from start") } -} +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-23.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-23-flatMapConcat.kt similarity index 95% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-23.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-23-flatMapConcat.kt index 4a41bae..3b2a7b1 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-23.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-23-flatMapConcat.kt @@ -11,13 +11,14 @@ import kotlinx.coroutines.runBlocking fun requestFlow23(i: Int): Flow = flow { emit("$i: First") - delay(500) // wait 500 ms + delay(5000) // wait 500 ms emit("$i: Second") } fun main() = runBlocking { val startTime = System.currentTimeMillis() // remember the start time - (1..3).asFlow().onEach { delay(100) } // a number every 100 ms + + (1..3).asFlow().onEach { delay(100) } // a number every 100 ms .flatMapConcat { requestFlow23(it) } .collect { value -> // collect and print println("$value at ${System.currentTimeMillis() - startTime} ms from start") diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-24.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-24-flatMapMerge.kt similarity index 96% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-24.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-24-flatMapMerge.kt index c7847cf..fe958da 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-24.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-24-flatMapMerge.kt @@ -11,12 +11,13 @@ import kotlinx.coroutines.runBlocking fun requestFlow24(i: Int): Flow = flow { emit("$i: First") - delay(500) // wait 500 ms + delay(5000) // wait 500 ms emit("$i: Second") } fun main() = runBlocking { val startTime = System.currentTimeMillis() // remember the start time + (1..3).asFlow().onEach { delay(100) } // a number every 100 ms .flatMapMerge { requestFlow24(it) } .collect { value -> // collect and print diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-25.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-25-flatMapLatest.kt similarity index 96% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-25.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-25-flatMapLatest.kt index 0240bf7..64bdf55 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-25.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-25-flatMapLatest.kt @@ -11,12 +11,13 @@ import kotlinx.coroutines.runBlocking fun requestFlow(i: Int): Flow = flow { emit("$i: First") - delay(500) // wait 500 ms + delay(5000) // wait 500 ms emit("$i: Second") } fun main() = runBlocking { val startTime = System.currentTimeMillis() // remember the start time + (1..3).asFlow().onEach { delay(100) } // a number every 100 ms .flatMapLatest { requestFlow(it) } .collect { value -> // collect and print diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-26.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-26-handle-exceptions-strategy-1.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-26.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-26-handle-exceptions-strategy-1.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-27.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-27-handle-exceptions-strategy-1.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-27.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-27-handle-exceptions-strategy-1.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-28.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-28-handle-exceptions-strategy-2.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-28.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-28-handle-exceptions-strategy-2.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-29.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-29-handle-exceptions-strategy-2.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-29.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-29-handle-exceptions-strategy-2.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-03.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-3.kt similarity index 58% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-03.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-3.kt index 1774c89..a45cf57 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-03.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-3.kt @@ -8,11 +8,23 @@ package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking -suspend fun foo3(): List { - delay(1000) // pretend we are doing something asynchronous here - return listOf(1, 2, 3) +fun main() { + foo2().forEach { value -> println(value) } + + runBlocking { + foo3().forEach { value -> println(value) } + } } -fun main() = runBlocking { - foo3().forEach { value -> println(value) } +fun foo2(): Sequence = sequence { // sequence builder + for (i in 1..3) { + Thread.sleep(1000) // pretend we are computing it + yield(i) // yield next value + } } + + +suspend fun foo3(): List { + delay(1000) // pretend we are doing something asynchronous here + return listOf(1, 2, 3) +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-30.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-30-handle-exceptions-strategy-2.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-30.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-30-handle-exceptions-strategy-2.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-1.kt similarity index 82% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-1.kt index 63c765f..b2d2742 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-1.kt @@ -10,12 +10,12 @@ import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.runBlocking -fun foo31(): Flow = (1..3).asFlow() +fun foo31a(): Flow = (1..3).asFlow() fun main() = runBlocking { try { - foo31().collect { value -> println(value) } + foo31a().collect { value -> println(value) } } finally { println("Done") } -} +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-2.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-2.kt new file mode 100644 index 0000000..18ceb81 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-2.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.runBlocking + +fun foo31b(): Flow = flow { + for (i in 1..3) { + println("Emitting $i") + emit(i) // emit next value + } +} + +fun main() = runBlocking { + try { + foo31b().collect { value -> + println(value) + check(value <= 1) { "Collected $value" } + } + } catch (e: Throwable) { + println("Caught $e") + } finally { + println("done") + } +} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-32.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-32-onCompletion.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-32.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-32-onCompletion.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-33.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-33-onCompletion-and-catch.kt similarity index 70% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-33.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-33-onCompletion-and-catch.kt index 65fe46d..31edef4 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-33.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-33-onCompletion-and-catch.kt @@ -9,13 +9,17 @@ import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking fun foo33(): Flow = flow { - emit(1) - throw RuntimeException() + for (i in 1..3) { + emit(i) + } } fun main() = runBlocking { foo33() - .onCompletion { cause -> if (cause != null) println("Flow completed exceptionally") } - .catch { cause -> println("Caught exception") } + .onEach { + check(it <= 1) { "Collected $it" } + } + .onCompletion { cause -> if (cause != null) println("Flow completed exceptionally - $cause") } + .catch { cause -> println("Caught exception - $cause") } .collect { value -> println(value) } } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-34.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-34-onCompletion-and-catch.kt similarity index 74% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-34.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-34-onCompletion-and-catch.kt index 7c18090..ee65cfb 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-34.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-34-onCompletion-and-catch.kt @@ -5,17 +5,15 @@ // This file was automatically generated from flow.md by Knit tool. Do not edit. package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.onCompletion +import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking fun foo34(): Flow = (1..3).asFlow() -fun main() = runBlocking { +fun main() = runBlocking { foo34() .onCompletion { cause -> println("Flow completed with $cause") } + .catch { cause -> println("Caught exception - $cause") } // cannot catch downstream exceptions .collect { value -> check(value <= 1) { "Collected $value" } println(value) diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-35.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-35-collect-is-suspending.kt similarity index 81% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-35.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-35-collect-is-suspending.kt index cce024b..142d5a0 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-35.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-35-collect-is-suspending.kt @@ -6,17 +6,14 @@ package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.runBlocking -// Imitate a flow of events -fun events35(): Flow = (1..3).asFlow().onEach { delay(100) } fun main() = runBlocking { - events35() + (1..3).asFlow().onEach { delay(10000) } .onEach { event -> println("Event: $event") } .collect() // <--- Collecting the flow waits println("Done") diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-36.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-36-launchIn-is-fire-and-forget.kt similarity index 80% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-36.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-36-launchIn-is-fire-and-forget.kt index c4961c8..ad9aeee 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-36.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-36-launchIn-is-fire-and-forget.kt @@ -6,18 +6,23 @@ package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.runBlocking -// Imitate a flow of events -fun events(): Flow = (1..3).asFlow().onEach { delay(100) } fun main() = runBlocking { - events() + (1..3).asFlow().onEach { delay(100) } .onEach { event -> println("Event: $event") } .launchIn(this) // <--- Launching the flow in a separate coroutine println("Done") -} +} + + +/* +launchIn() is a shorthand for + scope.launch{ + flow.collect() + } +* */ \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-37-launchIn-is-like-this.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-37-launchIn-is-like-this.kt new file mode 100644 index 0000000..e429e3f --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-37-launchIn-is-like-this.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// This file was automatically generated from flow.md by Knit tool. Do not edit. +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking + +fun main() = runBlocking { + launch { + (1..3).asFlow().onEach { delay(100) } + .onEach { event -> println("Event: $event") } + .collect() // <--- Launching the flow in a separate coroutine + } + println("Done") +} + +/* +launchIn() is a shorthand for + scope.launch{ + flow.collect() + } +* */ \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-38-flow-builder-does-cancellation-check.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-38-flow-builder-does-cancellation-check.kt new file mode 100644 index 0000000..f5dcb28 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-38-flow-builder-does-cancellation-check.kt @@ -0,0 +1,29 @@ +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.runBlocking + +/* +flow builder + flow { + ... + } +performs additional ensureActive checks for cancellation on each emitted value. +* */ + +fun foo(): Flow = flow { + for (i in 1..5) { + println("Emitting $i") + emit(i) + } +} + +fun main() = runBlocking { + foo().collect { value -> + if (value == 3) cancel() + println(value) + } +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-39-asFlow-operator-doesnt-do-cancellation-check.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-39-asFlow-operator-doesnt-do-cancellation-check.kt new file mode 100644 index 0000000..a1962c0 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-39-asFlow-operator-doesnt-do-cancellation-check.kt @@ -0,0 +1,18 @@ +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.runBlocking + +/* +Many flow operators don't do cancellation check for performance reasons. +For example, asFlow() doesn't do cancellation check. +* */ + +fun main() = runBlocking { + (1..5).asFlow().collect { value -> + if (value == 3) cancel() + println(value) + } +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-4.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-4.kt new file mode 100644 index 0000000..1751378 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-4.kt @@ -0,0 +1,25 @@ +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.runBlocking + +/* +* Since collect() is a suspending function, it can only be called from a coroutine or another suspending function. +* This is why you wrap the code with runBlocking(). +* */ +fun main() { + val namesFlow = flow { + val names = listOf("Jody", "Steve", "Lance", "Joe") + for (name in names) { + delay(1000) + emit(name) + } + } + + runBlocking { + namesFlow.collect { println(it) } + } +} + diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-40-make-asFlow-cancellable-way-1.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-40-make-asFlow-cancellable-way-1.kt new file mode 100644 index 0000000..554094e --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-40-make-asFlow-cancellable-way-1.kt @@ -0,0 +1,20 @@ +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.cancellable +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.runBlocking + +/* +Many flow operators don't do cancellation check for performance reasons. +For example, asFlow() doesn't do cancellation check. +asFlow().cancellable() makes asFlow() cancellable. +* */ + +fun main() = runBlocking { + (1..5).asFlow().cancellable().collect { value -> + if (value == 3) cancel() + println(value) + } +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-41-make-asFlow-cancellable-way-2.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-41-make-asFlow-cancellable-way-2.kt new file mode 100644 index 0000000..cd537d6 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-41-make-asFlow-cancellable-way-2.kt @@ -0,0 +1,24 @@ +package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground + +import kotlinx.coroutines.cancel +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.runBlocking + +/* +Many flow operators don't do cancellation check for performance reasons. +For example, asFlow() doesn't do cancellation check. +Before each emission, checking ensureActive() makes asFlow() cancellable. + +* */ + +fun main() = runBlocking { + (1..5).asFlow().onEach { currentCoroutineContext().ensureActive() } + .collect { value -> + if (value == 3) cancel() + println(value) + } +} \ No newline at end of file diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-05.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-5.kt similarity index 90% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-05.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-5.kt index 7a42598..07b80bc 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-05.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-5.kt @@ -11,19 +11,25 @@ import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking -fun foo5(): Flow = flow { - println("Flow started") - for (i in 1..3) { - delay(100) - emit(i) - } -} +/* +* To get all the values in the stream as they're emitted, use collect() +* */ fun main() = runBlocking { println("Calling foo...") val flow = foo5() + println("Calling collect...") flow.collect { value -> println(value) } + println("Calling collect again...") flow.collect { value -> println(value) } } + +fun foo5(): Flow = flow { + println("Flow started") + for (i in 1..3) { + delay(100) + emit(i) + } +} diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-04.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-6.kt similarity index 88% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-04.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-6.kt index 2b3d34f..06dad17 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-04.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-6.kt @@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -fun foo4(): Flow = flow { // flow builder +fun foo6(): Flow = flow { // flow builder for (i in 1..3) { delay(100) // pretend we are doing something useful here emit(i) // emit next value @@ -27,6 +27,8 @@ fun main() = runBlocking { delay(100) } } + // Collect the flow - foo4().collect { value -> println(value) } + foo6().collect { value -> println(value) } + println("end") } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-06.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-7.kt similarity index 89% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-06.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-7.kt index 375330a..1f74341 100644 --- a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-06.kt +++ b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-7.kt @@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeoutOrNull -fun foo6(): Flow = flow { +fun foo61(): Flow = flow { for (i in 1..3) { delay(100) println("Emitting $i") @@ -22,7 +22,7 @@ fun foo6(): Flow = flow { fun main() = runBlocking { withTimeoutOrNull(250) { // Timeout after 250ms - foo6().collect { value -> println(value) } + foo61().collect { value -> println(value) } } println("Done") } diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-07.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-8.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-07.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-8.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-08.kt b/Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-9.kt similarity index 100% rename from Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-08.kt rename to Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-9.kt diff --git a/Tutorial1-1CoroutinesBasics/src/main/res/layout/activity3_lifecycle_scope.xml b/Tutorial1-1CoroutinesBasics/src/main/res/layout/activity3_lifecycle_scope.xml new file mode 100644 index 0000000..01aa638 --- /dev/null +++ b/Tutorial1-1CoroutinesBasics/src/main/res/layout/activity3_lifecycle_scope.xml @@ -0,0 +1,38 @@ + + + + + + + + + +