├── .gitignore ├── External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── android │ │ └── kotlincoroutines │ │ └── main │ │ └── RefreshMainDataWorkTest.kt │ ├── debug │ └── java │ │ └── com │ │ └── example │ │ └── android │ │ └── kotlincoroutines │ │ └── fakes │ │ └── TestingFakes.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── android │ │ │ └── kotlincoroutines │ │ │ ├── KotlinCoroutinesApp.kt │ │ │ ├── main │ │ │ ├── MainActivity.kt │ │ │ ├── MainDatabase.kt │ │ │ ├── MainNetwork.kt │ │ │ ├── MainViewModel.kt │ │ │ ├── RefreshMainDataWork.kt │ │ │ └── TitleRepository.kt │ │ │ └── util │ │ │ ├── SkipNetworkInterceptor.kt │ │ │ └── ViewModelHelpers.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── android │ └── kotlincoroutines │ └── main │ ├── MainViewModelTest.kt │ ├── TitleRepositoryTest.kt │ └── utils │ ├── LiveDataTestExtensions.kt │ └── MainCoroutineScopeRule.kt ├── Tutorial1-1CoroutinesBasics ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── smarttoolfactory │ │ └── tutorial1_1coroutinesbasics │ │ └── MeasurmentDaoTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── smarttoolfactory │ │ │ └── tutorial1_1coroutinesbasics │ │ │ ├── MainActivity.kt │ │ │ ├── adapter │ │ │ ├── BaseAdapter.kt │ │ │ └── ChapterSelectionAdapter.kt │ │ │ ├── chapter1_basics │ │ │ ├── Activity1Basics.kt │ │ │ ├── Fragment1Basics.kt │ │ │ └── Fragment2Basics.kt │ │ │ ├── chapter2_scopes │ │ │ └── Activity2CoroutineScope.kt │ │ │ ├── chapter3_lifecycle │ │ │ ├── Activity3CoroutineLifecycle.kt │ │ │ └── Activity3LifecycleScope.kt │ │ │ ├── chapter4_supervisorjob │ │ │ └── Activity4SupervisorJob.kt │ │ │ ├── chapter5_viewmodel │ │ │ ├── Activity5ViewModelRxJava.kt │ │ │ ├── Activity5ViewModelScope.kt │ │ │ ├── CoroutinesViewModel.kt │ │ │ ├── CoroutinesViewModelWithCustomScope.kt │ │ │ └── RxJavaViewModel.kt │ │ │ ├── chapter6_network │ │ │ ├── Activity6Network.kt │ │ │ ├── PostsCoroutineViewModel.kt │ │ │ ├── PostsRepository.kt │ │ │ ├── PostsUseCase.kt │ │ │ └── api │ │ │ │ ├── DataResult.kt │ │ │ │ ├── Post.kt │ │ │ │ └── PostApi.kt │ │ │ ├── chapter7_database │ │ │ ├── Activity7_1Database.kt │ │ │ ├── Activity7_2DatabaseThreading.kt │ │ │ ├── MeasurementRepository.kt │ │ │ ├── MeasurementUseCase.kt │ │ │ ├── MeasurementViewModel.kt │ │ │ └── database │ │ │ │ └── Database.kt │ │ │ ├── chapter8_single_source_of_truth │ │ │ └── Activity8SingleSourceOfTruth.kt │ │ │ ├── model │ │ │ ├── ActivityClassModel.kt │ │ │ └── ViewState.kt │ │ │ ├── playground │ │ │ ├── basics.md │ │ │ ├── coroutineScope-1.kt │ │ │ ├── example-basic-01.kt │ │ │ ├── example-basic-02.kt │ │ │ ├── example-basic-03.kt │ │ │ ├── example-basic-04.kt │ │ │ ├── example-basic-05.kt │ │ │ ├── example-basic-06.kt │ │ │ ├── example-basic-07.kt │ │ │ ├── example-basic-08.kt │ │ │ ├── example-basic-09.kt │ │ │ ├── example-basic-10.kt │ │ │ ├── example-cancel-01.kt │ │ │ ├── example-cancel-02.kt │ │ │ ├── example-cancel-03.kt │ │ │ ├── example-cancel-04.kt │ │ │ ├── example-cancel-05.kt │ │ │ ├── example-cancel-06.kt │ │ │ ├── example-cancel-07.kt │ │ │ ├── example-channel-04.kt │ │ │ ├── example-channel-05.kt │ │ │ ├── example-channel-06.kt │ │ │ ├── example-channel-07.kt │ │ │ ├── example-channel-08.kt │ │ │ ├── example-channel-09.kt │ │ │ ├── example-channel-1.kt │ │ │ ├── example-channel-10.kt │ │ │ ├── example-channel-2.kt │ │ │ ├── example-channel-3.kt │ │ │ ├── example-channel-4.kt │ │ │ ├── example-compose-01.kt │ │ │ ├── example-compose-02.kt │ │ │ ├── example-compose-03.kt │ │ │ ├── example-compose-04.kt │ │ │ ├── example-compose-05.kt │ │ │ ├── example-compose-06.kt │ │ │ ├── example-context-01.kt │ │ │ ├── example-context-02.kt │ │ │ ├── example-context-03.kt │ │ │ ├── example-context-04.kt │ │ │ ├── example-context-05.kt │ │ │ ├── example-context-06.kt │ │ │ ├── example-context-07.kt │ │ │ ├── example-context-08.kt │ │ │ ├── example-context-09.kt │ │ │ ├── example-context-10.kt │ │ │ ├── example-context-11.kt │ │ │ ├── example-exceptions-01.kt │ │ │ ├── example-exceptions-02.kt │ │ │ ├── example-exceptions-03.kt │ │ │ ├── example-exceptions-04.kt │ │ │ ├── example-exceptions-05.kt │ │ │ ├── example-exceptions-06.kt │ │ │ ├── example-flow-1.kt │ │ │ ├── example-flow-10a.kt │ │ │ ├── example-flow-10b.kt │ │ │ ├── example-flow-11.kt │ │ │ ├── example-flow-12.kt │ │ │ ├── example-flow-13.kt │ │ │ ├── example-flow-14.kt │ │ │ ├── example-flow-15-flowOn.kt │ │ │ ├── example-flow-16.kt │ │ │ ├── example-flow-17-1-without-buffer.kt │ │ │ ├── example-flow-17-2-buffer.kt │ │ │ ├── example-flow-17-3-buffer.kt │ │ │ ├── example-flow-18-conflate.kt │ │ │ ├── example-flow-19-collectLatest.kt │ │ │ ├── example-flow-2.kt │ │ │ ├── example-flow-20-onEach.kt │ │ │ ├── example-flow-20-zip.kt │ │ │ ├── example-flow-21-zip.kt │ │ │ ├── example-flow-22-combine-1.kt │ │ │ ├── example-flow-22-combine-2.kt │ │ │ ├── example-flow-23-flatMapConcat.kt │ │ │ ├── example-flow-24-flatMapMerge.kt │ │ │ ├── example-flow-25-flatMapLatest.kt │ │ │ ├── example-flow-26-handle-exceptions-strategy-1.kt │ │ │ ├── example-flow-27-handle-exceptions-strategy-1.kt │ │ │ ├── example-flow-28-handle-exceptions-strategy-2.kt │ │ │ ├── example-flow-29-handle-exceptions-strategy-2.kt │ │ │ ├── example-flow-3.kt │ │ │ ├── example-flow-30-handle-exceptions-strategy-2.kt │ │ │ ├── example-flow-31-finally-1.kt │ │ │ ├── example-flow-31-finally-2.kt │ │ │ ├── example-flow-32-onCompletion.kt │ │ │ ├── example-flow-33-onCompletion-and-catch.kt │ │ │ ├── example-flow-34-onCompletion-and-catch.kt │ │ │ ├── example-flow-35-collect-is-suspending.kt │ │ │ ├── example-flow-36-launchIn-is-fire-and-forget.kt │ │ │ ├── example-flow-37-launchIn-is-like-this.kt │ │ │ ├── example-flow-38-flow-builder-does-cancellation-check.kt │ │ │ ├── example-flow-39-asFlow-operator-doesnt-do-cancellation-check.kt │ │ │ ├── example-flow-4.kt │ │ │ ├── example-flow-40-make-asFlow-cancellable-way-1.kt │ │ │ ├── example-flow-41-make-asFlow-cancellable-way-2.kt │ │ │ ├── example-flow-5.kt │ │ │ ├── example-flow-6.kt │ │ │ ├── example-flow-7.kt │ │ │ ├── example-flow-8.kt │ │ │ ├── example-flow-9.kt │ │ │ ├── example-select-01.kt │ │ │ ├── example-select-02.kt │ │ │ ├── example-select-03.kt │ │ │ ├── example-select-04.kt │ │ │ ├── example-select-05.kt │ │ │ ├── example-supervision-01.kt │ │ │ ├── example-supervision-02.kt │ │ │ ├── example-supervision-03.kt │ │ │ ├── example-sync-01.kt │ │ │ ├── example-sync-02.kt │ │ │ ├── example-sync-03.kt │ │ │ ├── example-sync-04.kt │ │ │ ├── example-sync-05.kt │ │ │ ├── example-sync-06.kt │ │ │ ├── example-sync-07.kt │ │ │ ├── jobs-01-coroutineScope.cancel().kt │ │ │ ├── jobs-02-parentJob.cancel().kt │ │ │ ├── jobs-03-childJob.cancel().kt │ │ │ ├── jobs-04-throw-exception-in-parent-Job.kt │ │ │ ├── jobs-05-throw-exception-in-child-Job-without-SupervisorJob.kt │ │ │ ├── jobs-06-throw-exception-in-child-Job-with-wrong-usage-of-SupervisorJob.kt │ │ │ ├── jobs-07-parentJob.cancel()-alternative-1.kt │ │ │ ├── jobs-08-parentJob.cancel()-alternative-2.kt │ │ │ ├── jobs-09-coroutineContext[Job].kt │ │ │ ├── jobs-10-invokeOnCompletion.kt │ │ │ ├── jobs-11-invokeOnCompletion.kt │ │ │ ├── jobs-12 - using try catch rather than supervisorJob.kt │ │ │ ├── jobs-13.1 - supervisorJob.kt │ │ │ ├── jobs-13.2 - supervisorJob.kt │ │ │ ├── jobs-14.1 - supervisorJob.kt │ │ │ ├── jobs-14.2 - supervisorJob.kt │ │ │ ├── jobs-15.1 - supervisorJob.kt │ │ │ ├── jobs-15.2 - supervisorScope.kt │ │ │ ├── jobs-16 - yield.kt │ │ │ ├── random-practice-1.kt │ │ │ ├── random-practice-10-order-of-execution-.kt │ │ │ ├── random-practice-11-order-of-execution-coroutineScope-and-launch-together.kt │ │ │ ├── random-practice-2.kt │ │ │ ├── random-practice-3.kt │ │ │ ├── random-practice-4.kt │ │ │ ├── random-practice-5.kt │ │ │ ├── random-practice-6.kt │ │ │ ├── random-practice-7-give-name-to-a-coroutine.kt │ │ │ ├── random-practice-8-CoroutineStart.LAZY.kt │ │ │ └── random-practice-9-CoroutineStart.LAZY.kt │ │ │ ├── retrofitexample │ │ │ ├── ReqResAPI.kt │ │ │ ├── RetrofitActivity.kt │ │ │ └── UsersResponse.kt │ │ │ └── util │ │ │ ├── ActivityDataBinding.kt │ │ │ ├── BindingAdapters.kt │ │ │ ├── Event.kt │ │ │ ├── FragmentDataBinding.kt │ │ │ ├── LifecycleOwnerExtension.kt │ │ │ └── RxJavaExtension.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity1_basics.xml │ │ ├── activity2_scope.xml │ │ ├── activity3_coroutine_lifecycle.xml │ │ ├── activity3_lifecycle_scope.xml │ │ ├── activity4_supervisor_job.xml │ │ ├── activity5_viewmodel_coroutines.xml │ │ ├── activity5_viewmodel_rxjava.xml │ │ ├── activity6_retrofit.xml │ │ ├── activity7_database.xml │ │ ├── activity8_ssot.xml │ │ ├── activity_main.xml │ │ ├── activity_retrofit.xml │ │ ├── fragment1_basics.xml │ │ ├── fragment2_basics.xml │ │ └── rowlayout.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ ├── java │ └── com │ │ └── smarttoolfactory │ │ └── tutorial1_1coroutinesbasics │ │ ├── chapter5_viewmodel │ │ ├── CoroutinesViewModelTest.kt │ │ └── CoroutinesViewModelWithCustomScopeTest.kt │ │ ├── chapter6_network │ │ ├── AbstractPostApiTest.kt │ │ ├── PostApiCoroutinesTest.kt │ │ ├── PostApiRxJavaTest.kt │ │ ├── PostsCoroutineViewModelTest.kt │ │ ├── PostsRepositoryTest.kt │ │ └── test_suite │ │ │ └── PostNetworkJUnit4TestSuite.kt │ │ ├── chapter7_database │ │ ├── MeasurementUseCaseTest.kt │ │ └── MeasurementViewModelTest.kt │ │ └── util │ │ ├── LiveDataTestUtil.kt │ │ ├── ReadResounceUtil.kt │ │ └── rules │ │ ├── MockWebServerRule.kt │ │ └── TestCoroutineRule.kt │ └── resources │ └── posts.json ├── Tutorial2-1FlowBasics ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── smarttoolfactory │ │ └── tutorial2_1flowbasics │ │ ├── PostDaoCoroutinesFlowTest.kt │ │ └── PostDaoRxJavaTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── mock │ │ │ └── response.json │ ├── java │ │ └── com │ │ │ └── smarttoolfactory │ │ │ └── tutorial2_1flowbasics │ │ │ ├── MainActivity.kt │ │ │ ├── adapter │ │ │ ├── BaseAdapter.kt │ │ │ ├── ChapterSelectionAdapter.kt │ │ │ └── PostListAdapter.kt │ │ │ ├── chapter2_network │ │ │ ├── Activity2Network.kt │ │ │ ├── PostRemoteRepository.kt │ │ │ ├── PostRemoteUseCase.kt │ │ │ └── PostRemoteViewModel.kt │ │ │ ├── chapter3_database │ │ │ ├── Activity3Database.kt │ │ │ ├── PostDBRepository.kt │ │ │ ├── PostDBUseCase.kt │ │ │ ├── PostDBViewModel.kt │ │ │ └── mock │ │ │ │ └── MockProductFactory.kt │ │ │ ├── chapter4_single_source_of_truth │ │ │ ├── Activity4SingleSourceOfTruth.kt │ │ │ ├── Activity4SingleSourceOfTruthRxJava3.kt │ │ │ ├── DispatcherProvider.kt │ │ │ ├── data │ │ │ │ ├── repository │ │ │ │ │ ├── PostRepository.kt │ │ │ │ │ └── PostRepositoryImpl.kt │ │ │ │ └── source │ │ │ │ │ └── DataSources.kt │ │ │ ├── data_alternative │ │ │ │ ├── PostDataSourceAlt.kt │ │ │ │ └── PostFlowRepositoryImpl.kt │ │ │ ├── domain │ │ │ │ ├── GetPostsUseCaseFlow.kt │ │ │ │ └── GetPostsUseCaseRxJava3.kt │ │ │ └── post_list │ │ │ │ ├── AbstractPostViewModel.kt │ │ │ │ ├── PostListFragment.kt │ │ │ │ ├── PostListFragmentRxJava3.kt │ │ │ │ ├── PostViewModel.kt │ │ │ │ └── PostViewModelRxJava3.kt │ │ │ ├── data │ │ │ ├── api │ │ │ │ └── PostApi.kt │ │ │ ├── db │ │ │ │ ├── PostDatabaseFlow.kt │ │ │ │ └── PostDatabaseRxJava.kt │ │ │ ├── mapper │ │ │ │ └── Mappers.kt │ │ │ └── model │ │ │ │ ├── Post.kt │ │ │ │ ├── PostDTO.kt │ │ │ │ ├── PostEntity.kt │ │ │ │ └── ViewState.kt │ │ │ ├── di │ │ │ └── ServiceLocator.kt │ │ │ ├── model │ │ │ └── ActivityClassModel.kt │ │ │ └── util │ │ │ ├── EmptyDataException.kt │ │ │ ├── Event.kt │ │ │ ├── RxJavaExtension.kt │ │ │ └── ViewBindings.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── avatar_1_raster.png │ │ ├── avatar_2_raster.png │ │ ├── avatar_3_raster.png │ │ ├── avatar_4_raster.png │ │ ├── avatar_5_raster.png │ │ ├── avatar_6_raster.png │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity2_network.xml │ │ ├── activity3_database.xml │ │ ├── activity4_single_source_of_truth.xml │ │ ├── activity_main.xml │ │ ├── fragment_post_list.xml │ │ ├── row_post.xml │ │ └── rowlayout.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── navigation │ │ ├── nav_graph_post_list.xml │ │ └── nav_graph_post_list_rxjava3.xml │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ ├── test-shared │ └── java │ │ └── com │ │ └── smarttoolfactory │ │ └── tutorial2_1flowbasics │ │ ├── ReadResourceUtil.kt │ │ ├── TestCoroutineRule.kt │ │ ├── flow │ │ └── FlowTestUtil.kt │ │ └── livedata │ │ └── LiveDataTestUtil.kt │ └── test │ ├── java │ └── com │ │ └── smarttoolfactory │ │ └── tutorial2_1flowbasics │ │ ├── FlowTestObserverTest.kt │ │ ├── base │ │ ├── AbstractPostApiTest.kt │ │ └── BaseCoroutineJUnit5Test.kt │ │ ├── chapter1_operators │ │ └── OperatorTest.kt │ │ ├── chapter2_network │ │ ├── PostApiTest.kt │ │ ├── PostNetworkViewModelTest.kt │ │ ├── PostRemoteRepositoryTest.kt │ │ └── PostRemoteUseCaseTest.kt │ │ ├── chapter3_database │ │ ├── PostDBRepositoryTest.kt │ │ ├── PostDBUseCaseTest.kt │ │ └── PostDBViewModelTest.kt │ │ └── chapter4_single_source_of_truth │ │ ├── data │ │ └── repository │ │ │ ├── PostRepoRxJava3ImplTest.kt │ │ │ └── PostRepositoryImplTest.kt │ │ └── domain │ │ ├── GetPostsUseCaseFlowTest.kt │ │ └── GetPostsUseCaseRxJava3Test.kt │ └── resources │ └── response.json ├── build.gradle ├── features └── post_detail │ ├── .gitignore │ ├── build.gradle │ └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── smarttoolfactory │ │ └── post_detail │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── smarttoolfactory │ │ │ └── post_detail │ │ │ ├── PostBinding.kt │ │ │ └── PostDetailFragment.kt │ └── res │ │ ├── layout │ │ └── fragment_post_detail.xml │ │ └── navigation │ │ └── nav_graph_post_detail.xml │ └── test │ └── java │ └── com │ └── smarttoolfactory │ └── post_detail │ └── ExampleUnitTest.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | #3F51B5 20 | #303F9F 21 | #FF4081 22 | 23 | -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | Kotlin Coroutines 19 | Click to start 20 | 21 | -------------------------------------------------------------------------------- /External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/adapter/ChapterSelectionAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.adapter 2 | 3 | 4 | import com.smarttoolfactory.tutorial1_1basics.R 5 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.model.ActivityClassModel 6 | 7 | 8 | /** 9 | * Process to create Adapter is listed below: 10 | * * 1- Inflate layout and create binding object with DataBindingUtil.inflate 11 | * inside onCreateViewHolder() and create ViewHolder 12 | * 13 | * * 2- Get binding object inside constructor of MyViewHolder constructor 14 | * 15 | * * 3- Bind items to rows inside onCreateViewHolder() method 16 | * 17 | */ 18 | 19 | // Provide a suitable constructor (depends on the kind of data set) 20 | class ChapterSelectionAdapter(private val data: List) : BaseAdapter() { 21 | 22 | override fun getDataAtPosition(position: Int): Any { 23 | return data[position] 24 | } 25 | 26 | 27 | override fun getLayoutIdForType(viewType: Int): Int { 28 | return R.layout.rowlayout 29 | } 30 | 31 | 32 | override fun getItemCount(): Int { 33 | return data.size 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter5_viewmodel/Activity5ViewModelRxJava.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter5_viewmodel 2 | 3 | import android.os.Bundle 4 | import androidx.activity.viewModels 5 | import androidx.appcompat.app.AppCompatActivity 6 | import com.smarttoolfactory.tutorial1_1basics.databinding.Activity5ViewmodelRxjavaBinding 7 | 8 | class Activity5ViewModelRxJava : AppCompatActivity() { 9 | 10 | private val viewModel: RxJavaViewModel by viewModels() 11 | 12 | private val dataBinding by lazy { 13 | Activity5ViewmodelRxjavaBinding.inflate(layoutInflater) 14 | } 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setContentView(dataBinding.root) 19 | 20 | dataBinding.apply { 21 | lifecycleOwner = this@Activity5ViewModelRxJava 22 | viewModel = this@Activity5ViewModelRxJava.viewModel 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter6_network/Activity6Network.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.lifecycle.ViewModelProvider 6 | import com.smarttoolfactory.tutorial1_1basics.databinding.Activity6RetrofitBinding 7 | 8 | class Activity6Network : AppCompatActivity() { 9 | 10 | private val viewModel by lazy { 11 | 12 | ViewModelProvider( 13 | this, 14 | PostCoroutineViewModelFactory() 15 | ).get(PostsCoroutineViewModel::class.java) 16 | } 17 | 18 | private val dataBinding by lazy { 19 | Activity6RetrofitBinding.inflate(layoutInflater) 20 | } 21 | 22 | override fun onCreate(savedInstanceState: Bundle?) { 23 | super.onCreate(savedInstanceState) 24 | setContentView(dataBinding.root) 25 | 26 | dataBinding.apply { 27 | lifecycleOwner = this@Activity6Network 28 | dataBinding.viewModel = this@Activity6Network.viewModel 29 | } 30 | 31 | /* 32 | Simple comparison between sequential and parallel networking calls 33 | */ 34 | viewModel.doSomeSequentialNetworkCalls() 35 | viewModel.doSomeParallelNetworkCalls() 36 | viewModel.doSomeParallelNetworkCallsWithLaunch() 37 | } 38 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter6_network/PostsUseCase.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network 2 | 3 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.api.DataResult 4 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.api.Post 5 | import retrofit2.Call 6 | 7 | class PostsUseCase(private val postsRepository: PostsRepository) { 8 | 9 | fun getPostsWithCall(): Call> { 10 | return postsRepository.getPostsWithCall() 11 | } 12 | 13 | suspend fun getPosts(): DataResult> { 14 | return postsRepository.getPostResult() 15 | } 16 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter6_network/api/DataResult.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.api 2 | 3 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.api.Status.* 4 | 5 | 6 | sealed class DataResult( 7 | val status: Status, 8 | val data: T? = null, 9 | val error: Throwable? = null 10 | ) { 11 | 12 | class Loading : DataResult(LOADING) 13 | class Success(data: T) : DataResult(SUCCESS, data = data) 14 | class Error(error: Throwable) : DataResult(ERROR, error = error) 15 | 16 | } 17 | 18 | 19 | enum class Status { 20 | LOADING, 21 | SUCCESS, 22 | ERROR 23 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter6_network/api/Post.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.api 2 | 3 | data class Post(val id:Int, 4 | val userId:Int, 5 | val title:String, 6 | val body:String) -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter7_database/Activity7_1Database.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter7_database 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.lifecycle.ViewModelProvider 6 | import com.smarttoolfactory.tutorial1_1basics.databinding.Activity7DatabaseBinding 7 | 8 | class Activity7_1Database : AppCompatActivity() { 9 | 10 | private val viewModel by lazy { 11 | ViewModelProvider( 12 | this, 13 | MeasurementViewModelFactory(application) 14 | ).get(MeasurementViewModel::class.java) 15 | } 16 | 17 | private val dataBinding by lazy { 18 | Activity7DatabaseBinding.inflate(layoutInflater) 19 | } 20 | 21 | override fun onCreate(savedInstanceState: Bundle?) { 22 | super.onCreate(savedInstanceState) 23 | setContentView(dataBinding.root) 24 | 25 | dataBinding.apply { 26 | lifecycleOwner = this@Activity7_1Database 27 | dataBinding.viewModel = this@Activity7_1Database.viewModel 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter7_database/MeasurementRepository.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter7_database 2 | 3 | import androidx.lifecycle.LiveData 4 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter7_database.database.Measurement 5 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter7_database.database.MeasurementDao 6 | 7 | class MeasurementRepository(private val measurementDao: MeasurementDao) { 8 | 9 | 10 | suspend fun insertMeasurementAsync(measurement: Measurement): Long { 11 | return measurementDao.insertAsync(measurement) 12 | } 13 | 14 | suspend fun getMeasurementsAsync(): List { 15 | return measurementDao.getMeasurementsAsync() 16 | } 17 | 18 | fun getMeasurements(): LiveData> { 19 | return measurementDao.getMeasurements() 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter7_database/MeasurementUseCase.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter7_database 2 | 3 | import androidx.lifecycle.LiveData 4 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter7_database.database.Measurement 5 | 6 | class MeasurementUseCase(private val measurementRepository: MeasurementRepository) { 7 | 8 | suspend fun insertMeasurementAsync(measurement: Measurement): Long { 9 | return measurementRepository.insertMeasurementAsync(measurement) 10 | } 11 | 12 | suspend fun getMeasurementsAsync(): List { 13 | return measurementRepository.getMeasurementsAsync() 14 | } 15 | 16 | fun getMeasurements(): LiveData> { 17 | return measurementRepository.getMeasurements() 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter8_single_source_of_truth/Activity8SingleSourceOfTruth.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter8_single_source_of_truth 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | 6 | class Activity8SingleSourceOfTruth: AppCompatActivity() { 7 | 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/model/ActivityClassModel.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.model 2 | 3 | data class ActivityClassModel(val clazz: Class<*>) 4 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/model/ViewState.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.model 2 | 3 | import androidx.annotation.VisibleForTesting 4 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.api.Status 5 | 6 | 7 | class ViewState( 8 | val status: Status, 9 | val data: T? = null, 10 | val error: Throwable? = null 11 | ) { 12 | fun isLoading() = status == Status.LOADING 13 | 14 | fun getErrorMessage() = error?.message 15 | 16 | fun shouldShowErrorMessage() = error != null 17 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/coroutineScope-1.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.coroutineScope 4 | import kotlinx.coroutines.launch 5 | import kotlinx.coroutines.runBlocking 6 | 7 | /* 8 | * 🔥 launch returns immediately but inside of launch not eecuted immediately. non-blocking code after launch is executed firstly, then inside of launch is executed. 9 | * 🐲 coroutineScope is a blocking code. Code execution does not go to following line, 10 | * waits for completion of inside of coroutineScope and coroutines started before coroutineScope. Thus printed 3 1 2. 11 | * 12 | * https://stackoverflow.com/questions/53535977/coroutines-runblocking-vs-coroutinescope/53536713#53536713 önce buna bak 13 | * */ 14 | 15 | fun main() = runBlocking { 16 | launch { 17 | println("1") 18 | } 19 | 20 | coroutineScope { 21 | launch { 22 | println("2") 23 | } 24 | 25 | println("3") 26 | } 27 | 28 | coroutineScope { 29 | launch { 30 | println("4") 31 | } 32 | 33 | println("5") 34 | } 35 | 36 | launch { 37 | println("6") 38 | } 39 | 40 | for (i in 7..100) { 41 | println(i.toString()) 42 | } 43 | 44 | println("101") 45 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-01.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.GlobalScope 4 | import kotlinx.coroutines.delay 5 | import kotlinx.coroutines.launch 6 | 7 | fun main() { 8 | GlobalScope.launch { // launch a new coroutine in background and continue 9 | delay(1000L) // non-blocking delay for 1 second (default time unit is ms) 10 | println("World!") // print after delay 11 | } 12 | println("Hello,") // main thread continues while coroutine is delayed 13 | Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive 14 | } 15 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() { 14 | GlobalScope.launch { // launch a new coroutine in background and continue 15 | delay(1000L) 16 | println("World!") 17 | } 18 | println("Hello,") // main thread continues here immediately 19 | runBlocking { // but this expression blocks the main thread 20 | delay(2000L) // ... while we delay for 2 seconds to keep JVM alive 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { // start main coroutine 14 | GlobalScope.launch { // launch a new coroutine in background and continue 15 | delay(1000L) 16 | println("World!") 17 | } 18 | println("Hello,") // main coroutine continues here immediately 19 | delay(2000L) // delaying for 2 seconds to keep JVM alive 20 | } 21 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | val job = GlobalScope.launch { // launch a new coroutine and keep a reference to its Job 15 | delay(1000L) 16 | println("World!") 17 | } 18 | println("Hello,") 19 | job.join() // wait until child coroutine completes 20 | } 21 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { // this: CoroutineScope 13 | launch { // launch a new coroutine in the scope of runBlocking 14 | delay(1000L) 15 | println("World!") 16 | } 17 | println("Hello,") 18 | } 19 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-06.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.coroutineScope 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { // this: CoroutineScope 14 | launch { 15 | delay(1000L) 16 | println("Task from runBlocking - ${Thread.currentThread().name}") 17 | } 18 | 19 | coroutineScope { // Creates a coroutine scope 20 | launch { 21 | delay(2000L) 22 | println("Task from nested launch - ${Thread.currentThread().name}") 23 | } 24 | 25 | delay(100L) 26 | println("Task from coroutine scope - ${Thread.currentThread().name}") // This line will be printed before the nested launch 27 | } 28 | 29 | println("Coroutine scope is over - ${Thread.currentThread().name}") // This line is not printed until the nested launch completes 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-07.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | launch { doWorld() } 14 | println("Hello,") 15 | } 16 | 17 | // this is your first suspending function 18 | suspend fun doWorld() { 19 | delay(1000L) 20 | println("World!") 21 | } 22 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-08.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | repeat(100_000) { // launch a lot of coroutines 14 | launch { 15 | delay(1000L) 16 | print(".") 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-basic-09.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from basics.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | GlobalScope.launch { 15 | repeat(1000) { i -> 16 | println("I'm sleeping $i ...") 17 | delay(500L) 18 | } 19 | } 20 | delay(1300L) // just quit after delay 21 | } 22 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-cancel-01.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from cancellation-and-timeouts.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | val job = launch { 14 | repeat(1000) { i -> 15 | println("job: I'm sleeping $i ...") 16 | delay(500L) 17 | } 18 | } 19 | delay(1300L) // delay a bit 20 | println("main: I'm tired of waiting!") 21 | job.cancel() // cancels the job 22 | job.join() // waits for job's completion 23 | println("main: Now I can quit.") 24 | } 25 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-cancel-02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from cancellation-and-timeouts.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | fun main() = runBlocking { 11 | val startTime = System.currentTimeMillis() 12 | val job = launch(Dispatchers.Default) { 13 | var nextPrintTime = startTime 14 | var i = 0 15 | while (i < 5) { // computation loop, just wastes CPU 16 | // print a message twice a second 17 | if (System.currentTimeMillis() >= nextPrintTime) { 18 | println("job: I'm sleeping ${i++} ...") 19 | nextPrintTime += 500L 20 | } 21 | } 22 | } 23 | delay(1300L) // delay a bit 24 | println("main: I'm tired of waiting!") 25 | job.cancelAndJoin() // cancels the job and waits for its completion 26 | println("main: Now I can quit.") 27 | } 28 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-cancel-03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from cancellation-and-timeouts.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | fun main() = runBlocking { 11 | val startTime = System.currentTimeMillis() 12 | val job = launch(Dispatchers.Default) { 13 | var nextPrintTime = startTime 14 | var i = 0 15 | while (isActive) { // cancellable computation loop 16 | // print a message twice a second 17 | if (System.currentTimeMillis() >= nextPrintTime) { 18 | println("job: I'm sleeping ${i++} ...") 19 | nextPrintTime += 500L 20 | } 21 | } 22 | } 23 | delay(1300L) // delay a bit 24 | println("main: I'm tired of waiting!") 25 | job.cancelAndJoin() // cancels the job and waits for its completion 26 | println("main: Now I can quit.") 27 | } 28 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-cancel-04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from cancellation-and-timeouts.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.cancelAndJoin 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | val job = launch { 15 | try { 16 | repeat(1000) { i -> 17 | println("job: I'm sleeping $i ...") 18 | delay(500L) 19 | } 20 | } finally { 21 | println("job: I'm running finally") 22 | } 23 | } 24 | delay(1300L) // delay a bit 25 | println("main: I'm tired of waiting!") 26 | job.cancelAndJoin() // cancels the job and waits for its completion 27 | println("main: Now I can quit.") 28 | } 29 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-cancel-05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from cancellation-and-timeouts.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | fun main() = runBlocking { 11 | val job = launch { 12 | try { 13 | repeat(1000) { i -> 14 | println("job: I'm sleeping $i ...") 15 | delay(500L) 16 | } 17 | } finally { 18 | withContext(NonCancellable) { 19 | println("job: I'm running finally") 20 | delay(1000L) 21 | println("job: And I've just delayed for 1 sec because I'm non-cancellable") 22 | } 23 | } 24 | } 25 | delay(1300L) // delay a bit 26 | println("main: I'm tired of waiting!") 27 | job.cancelAndJoin() // cancels the job and waits for its completion 28 | println("main: Now I can quit.") 29 | } 30 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-cancel-06.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from cancellation-and-timeouts.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.runBlocking 10 | import kotlinx.coroutines.withTimeout 11 | 12 | fun main() = runBlocking { 13 | withTimeout(1300L) { 14 | repeat(1000) { i -> 15 | println("I'm sleeping $i ...") 16 | delay(500L) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-cancel-07.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from cancellation-and-timeouts.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.runBlocking 10 | import kotlinx.coroutines.withTimeoutOrNull 11 | 12 | fun main() = runBlocking { 13 | val result = withTimeoutOrNull(1300L) { 14 | repeat(1000) { i -> 15 | println("I'm sleeping $i ...") 16 | delay(500L) 17 | } 18 | "Done" // will get cancelled before it produces this result 19 | } 20 | println("Result is $result") 21 | } 22 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.CoroutineScope 9 | import kotlinx.coroutines.cancelChildren 10 | import kotlinx.coroutines.channels.ReceiveChannel 11 | import kotlinx.coroutines.channels.produce 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun main() = runBlocking { 15 | val numbers = produceNumbers() // produces integers from 1 and on 16 | val squares = square(numbers) // squares integers 17 | repeat(5) { 18 | println(squares.receive()) // print first five 19 | } 20 | println("Done!") // we are done 21 | coroutineContext.cancelChildren() // cancel children coroutines 22 | } 23 | 24 | fun CoroutineScope.produceNumbers() = produce { 25 | var x = 1 26 | while (true) send(x++) // infinite stream of integers starting from 1 27 | } 28 | 29 | fun CoroutineScope.square(numbers: ReceiveChannel): ReceiveChannel = produce { 30 | for (x in numbers) send(x * x) 31 | } 32 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.CoroutineScope 9 | import kotlinx.coroutines.cancelChildren 10 | import kotlinx.coroutines.channels.ReceiveChannel 11 | import kotlinx.coroutines.channels.produce 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun main() = runBlocking { 15 | var cur = numbersFrom(2) 16 | repeat(10) { 17 | val prime = cur.receive() 18 | println(prime) 19 | cur = filter(cur, prime) 20 | } 21 | coroutineContext.cancelChildren() // cancel all children to let main finish 22 | } 23 | 24 | fun CoroutineScope.numbersFrom(start: Int) = produce { 25 | var x = start 26 | while (true) send(x++) // infinite stream of integers from start 27 | } 28 | 29 | fun CoroutineScope.filter(numbers: ReceiveChannel, prime: Int) = produce { 30 | for (x in numbers) if (x % prime != 0) send(x) 31 | } 32 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-06.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.CoroutineScope 9 | import kotlinx.coroutines.channels.ReceiveChannel 10 | import kotlinx.coroutines.channels.produce 11 | import kotlinx.coroutines.delay 12 | import kotlinx.coroutines.launch 13 | import kotlinx.coroutines.runBlocking 14 | 15 | fun main() = runBlocking { 16 | val producer = produceNumbers6() 17 | repeat(5) { launchProcessor(it, producer) } 18 | delay(950) 19 | producer.cancel() // cancel producer coroutine and thus kill them all 20 | } 21 | 22 | fun CoroutineScope.produceNumbers6() = produce { 23 | var x = 1 // start from 1 24 | while (true) { 25 | send(x++) // produce next 26 | delay(100) // wait 0.1s 27 | } 28 | } 29 | 30 | fun CoroutineScope.launchProcessor(id: Int, channel: ReceiveChannel) = launch { 31 | for (msg in channel) { 32 | println("Processor #$id received $msg") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-07.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.cancelChildren 9 | import kotlinx.coroutines.channels.Channel 10 | import kotlinx.coroutines.channels.SendChannel 11 | import kotlinx.coroutines.delay 12 | import kotlinx.coroutines.launch 13 | import kotlinx.coroutines.runBlocking 14 | 15 | fun main() = runBlocking { 16 | val channel = Channel() 17 | launch { sendString(channel, "foo", 200L) } 18 | launch { sendString(channel, "BAR!", 500L) } 19 | repeat(6) { // receive first six 20 | println(channel.receive()) 21 | } 22 | coroutineContext.cancelChildren() // cancel all children to let main finish 23 | } 24 | 25 | suspend fun sendString(channel: SendChannel, s: String, time: Long) { 26 | while (true) { 27 | delay(time) 28 | channel.send(s) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-08.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.channels.Channel 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | val channel = Channel(4) // create buffered channel 15 | val sender = launch { // launch sender coroutine 16 | repeat(10) { 17 | println("Sending $it") // print before sending each element 18 | channel.send(it) // will suspend when buffer is full 19 | } 20 | } 21 | // don't receive anything... just wait.... 22 | delay(1000) 23 | sender.cancel() // cancel sender coroutine 24 | } 25 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-09.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.cancelChildren 9 | import kotlinx.coroutines.channels.Channel 10 | import kotlinx.coroutines.delay 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.runBlocking 13 | 14 | data class Ball(var hits: Int) 15 | 16 | fun main() = runBlocking { 17 | val table = Channel() // a shared table 18 | launch { player("ping", table) } 19 | launch { player("pong", table) } 20 | table.send(Ball(0)) // serve the ball 21 | delay(1000) // delay 1 second 22 | coroutineContext.cancelChildren() // game over, cancel them 23 | } 24 | 25 | suspend fun player(name: String, table: Channel) { 26 | for (ball in table) { // receive the ball in a loop 27 | ball.hits++ 28 | println("$name $ball") 29 | delay(300) // wait a bit 30 | table.send(ball) // send the ball back 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-2.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.channels.Channel 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { // coroutine 1 14 | 15 | val channel = Channel() 16 | launch { // coroutine 2 17 | // this might be heavy CPU-consuming computation or async logic, we'll just send five squares 18 | for (x in 1..5) { 19 | println("send $x ") 20 | channel.send(x * x) 21 | } 22 | 23 | } 24 | // here we print five received integers: 25 | repeat(5) { 26 | delay(3000) 27 | println(channel.receive()) 28 | } 29 | println("Done!") 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-channel-3.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from channels.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.channels.Channel 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | 14 | val channel = Channel() 15 | launch { 16 | for (x in 1..5) 17 | channel.send(x * x) 18 | channel.close() // we're done sending 19 | } 20 | 21 | // here we print received values using `for` loop (until the channel is closed) 22 | // 1st way of receiving data from channel 23 | for (y in channel) println(y) 24 | // 2nd way of receiving data from channel 25 | /*repeat(5) { 26 | println(channel.receive()) }*/ 27 | 28 | println("Done!") 29 | } 30 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-compose-01.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from composing-suspending-functions.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.runBlocking 10 | import kotlin.system.measureTimeMillis 11 | 12 | fun main() = runBlocking { 13 | val time = measureTimeMillis { 14 | val one = doSomethingUsefulOne1() 15 | val two = doSomethingUsefulTwo1() 16 | println("The answer is ${one + two}") 17 | } 18 | println("Completed in $time ms") 19 | } 20 | 21 | suspend fun doSomethingUsefulOne1(): Int { 22 | delay(1000L) // pretend we are doing something useful here 23 | return 13 24 | } 25 | 26 | suspend fun doSomethingUsefulTwo1(): Int { 27 | delay(1000L) // pretend we are doing something useful here, too 28 | return 29 29 | } 30 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-compose-02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from composing-suspending-functions.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.async 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.runBlocking 11 | import kotlin.system.measureTimeMillis 12 | 13 | fun main() = runBlocking { 14 | val time = measureTimeMillis { 15 | val one = async { doSomethingUsefulOne2() } 16 | val two = async { doSomethingUsefulTwo2() } 17 | println("The answer is ${one.await() + two.await()}") 18 | } 19 | println("Completed in $time ms") 20 | } 21 | 22 | suspend fun doSomethingUsefulOne2(): Int { 23 | delay(1000L) // pretend we are doing something useful here 24 | return 13 25 | } 26 | 27 | suspend fun doSomethingUsefulTwo2(): Int { 28 | delay(1000L) // pretend we are doing something useful here, too 29 | return 29 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-compose-03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from composing-suspending-functions.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.CoroutineStart 9 | import kotlinx.coroutines.async 10 | import kotlinx.coroutines.delay 11 | import kotlinx.coroutines.runBlocking 12 | import kotlin.system.measureTimeMillis 13 | 14 | fun main() = runBlocking { 15 | val time = measureTimeMillis { 16 | val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne3() } 17 | val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo3() } 18 | // some computation 19 | one.start() // start the first one 20 | two.start() // start the second one 21 | println("The answer is ${one.await() + two.await()}") 22 | } 23 | println("Completed in $time ms") 24 | } 25 | 26 | suspend fun doSomethingUsefulOne3(): Int { 27 | delay(1000L) // pretend we are doing something useful here 28 | return 13 29 | } 30 | 31 | suspend fun doSomethingUsefulTwo3(): Int { 32 | delay(1000L) // pretend we are doing something useful here, too 33 | return 29 34 | } 35 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-compose-05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from composing-suspending-functions.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.async 9 | import kotlinx.coroutines.coroutineScope 10 | import kotlinx.coroutines.delay 11 | import kotlinx.coroutines.runBlocking 12 | import kotlin.system.measureTimeMillis 13 | 14 | fun main() = runBlocking { 15 | val time = measureTimeMillis { 16 | println("The answer is ${concurrentSum()}") 17 | } 18 | println("Completed in $time ms") 19 | } 20 | 21 | suspend fun concurrentSum(): Int = coroutineScope { 22 | val one = async { doSomethingUsefulOne() } 23 | val two = async { doSomethingUsefulTwo() } 24 | one.await() + two.await() 25 | } 26 | 27 | suspend fun doSomethingUsefulOne(): Int { 28 | delay(1000L) // pretend we are doing something useful here 29 | return 13 30 | } 31 | 32 | suspend fun doSomethingUsefulTwo(): Int { 33 | delay(1000L) // pretend we are doing something useful here, too 34 | return 29 35 | } 36 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-compose-06.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from composing-suspending-functions.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.async 9 | import kotlinx.coroutines.coroutineScope 10 | import kotlinx.coroutines.delay 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | try { 15 | failedConcurrentSum() 16 | } catch (e: ArithmeticException) { 17 | println("Computation failed with ArithmeticException") 18 | } 19 | } 20 | 21 | suspend fun failedConcurrentSum(): Int = coroutineScope { 22 | val one = async { 23 | try { 24 | delay(Long.MAX_VALUE) // Emulates very long computation 25 | 42 26 | } finally { 27 | println("First child was cancelled") 28 | } 29 | } 30 | val two = async { 31 | println("Second child throws an exception") 32 | throw ArithmeticException() 33 | } 34 | one.await() + two.await() 35 | } 36 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-01.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.newSingleThreadContext 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | launch { // context of the parent, main runBlocking coroutine 15 | println("main runBlocking : I'm working in thread ${Thread.currentThread().name}") 16 | } 17 | launch(Dispatchers.Unconfined) { // not confined -- will work with main thread 18 | println("Unconfined : I'm working in thread ${Thread.currentThread().name}") 19 | } 20 | launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher 21 | println("Default : I'm working in thread ${Thread.currentThread().name}") 22 | } 23 | launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread 24 | println("newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | launch(Dispatchers.Unconfined) { // not confined -- will work with main thread 15 | println("Unconfined : I'm working in thread ${Thread.currentThread().name}") 16 | delay(500) 17 | println("Unconfined : After delay in thread ${Thread.currentThread().name}") 18 | } 19 | launch { // context of the parent, main runBlocking coroutine 20 | println("main runBlocking: I'm working in thread ${Thread.currentThread().name}") 21 | delay(1000) 22 | println("main runBlocking: After delay in thread ${Thread.currentThread().name}") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.async 9 | import kotlinx.coroutines.runBlocking 10 | 11 | fun log3(msg: String) = println("[${Thread.currentThread().name}] $msg") 12 | 13 | fun main() = runBlocking { 14 | val a = async { 15 | log3("I'm computing a piece of the answer") 16 | 6 17 | } 18 | val b = async { 19 | log3("I'm computing another piece of the answer") 20 | 7 21 | } 22 | log3("The answer is ${a.await() * b.await()}") 23 | } 24 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.newSingleThreadContext 9 | import kotlinx.coroutines.runBlocking 10 | import kotlinx.coroutines.withContext 11 | 12 | fun log4(msg: String) = println("[${Thread.currentThread().name}] $msg") 13 | 14 | fun main() { 15 | newSingleThreadContext("Ctx1").use { ctx1 -> 16 | newSingleThreadContext("Ctx2").use { ctx2 -> 17 | runBlocking(ctx1) { 18 | log4("Started in ctx1") 19 | withContext(ctx2) { 20 | log4("Working in ctx2") 21 | } 22 | log4("Back to ctx1") 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.Job 9 | import kotlinx.coroutines.runBlocking 10 | 11 | fun main() = runBlocking { 12 | println("My job is ${coroutineContext[Job]}") 13 | } 14 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-07.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | // launch a coroutine to process some kind of incoming request 14 | val request = launch { 15 | repeat(3) { i -> // launch a few children jobs 16 | launch { 17 | delay((i + 1) * 200L) // variable delay 200ms, 400ms, 600ms 18 | println("Coroutine $i is done") 19 | } 20 | } 21 | println("request: I'm done and I don't explicitly join my children that are still active") 22 | } 23 | request.join() // wait for completion of the request, including all its children 24 | println("Now processing of the request is complete") 25 | } 26 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-08.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.CoroutineName 9 | import kotlinx.coroutines.async 10 | import kotlinx.coroutines.delay 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun log(msg: String) = println("[${Thread.currentThread().name}] $msg") 14 | 15 | fun main() = runBlocking(CoroutineName("main")) { 16 | log("Started main coroutine") 17 | // run two background value computations 18 | val v1 = async(CoroutineName("v1coroutine")) { 19 | delay(500) 20 | log("Computing v1") 21 | 252 22 | } 23 | val v2 = async(CoroutineName("v2coroutine")) { 24 | delay(1000) 25 | log("Computing v2") 26 | 6 27 | } 28 | log("The answer for v1 / v2 = ${v1.await() / v2.await()}") 29 | } 30 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-09.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.CoroutineName 9 | import kotlinx.coroutines.Dispatchers 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | launch(Dispatchers.Default + CoroutineName("test")) { 15 | println("I'm working in thread ${Thread.currentThread().name}") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-10.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | class Activity { 11 | private val mainScope = CoroutineScope(Dispatchers.Default) // use Default for test purposes 12 | 13 | fun destroy() { 14 | mainScope.cancel() 15 | } 16 | 17 | fun doSomething() { 18 | // launch ten coroutines for a demo, each working for a different time 19 | repeat(10) { i -> 20 | mainScope.launch { 21 | delay((i + 1) * 200L) // variable delay 200ms, 400ms, ... etc 22 | println("Coroutine $i is done") 23 | } 24 | } 25 | } 26 | } // class Activity ends 27 | 28 | fun main() = runBlocking { 29 | val activity = Activity() 30 | activity.doSomething() // run test function 31 | println("Launched coroutines") 32 | delay(500L) // delay for half a second 33 | println("Destroying activity!") 34 | activity.destroy() // cancels all coroutines 35 | delay(1000) // visually confirm that they don't work 36 | } 37 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-context-11.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from coroutine-context-and-dispatchers.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | val threadLocal = ThreadLocal() // declare thread-local variable 11 | 12 | fun main() = runBlocking { 13 | threadLocal.set("main") 14 | println("Pre-main, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'") 15 | val job = launch(Dispatchers.Default + threadLocal.asContextElement(value = "launch")) { 16 | println("Launch start, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'") 17 | yield() 18 | println("After yield, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'") 19 | } 20 | job.join() 21 | println("Post-main, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'") 22 | } 23 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-exceptions-01.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.async 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | val job = GlobalScope.launch { // root coroutine with launch 15 | println("Throwing exception from launch") 16 | throw IndexOutOfBoundsException() // Will be printed to the console by Thread.defaultUncaughtExceptionHandler 17 | } 18 | job.join() 19 | println("Joined failed job") 20 | val deferred = GlobalScope.async { // root coroutine with async 21 | println("Throwing exception from async") 22 | throw ArithmeticException() // Nothing is printed, relying on user to call await 23 | } 24 | try { 25 | deferred.await() 26 | println("Unreached") 27 | } catch (e: ArithmeticException) { 28 | println("Caught ArithmeticException") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-exceptions-02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | fun main() = runBlocking { 11 | val handler = CoroutineExceptionHandler { _, exception -> 12 | println("CoroutineExceptionHandler got $exception") 13 | } 14 | val job = GlobalScope.launch(handler) { // root coroutine, running in GlobalScope 15 | throw AssertionError() 16 | } 17 | val deferred = GlobalScope.async(handler) { // also root, but async instead of launch 18 | throw ArithmeticException() // Nothing will be printed, relying on user to call deferred.await() 19 | } 20 | joinAll(job, deferred) 21 | } 22 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-exceptions-03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | import kotlinx.coroutines.yield 12 | 13 | fun main() = runBlocking { 14 | val job = launch { 15 | val child = launch { 16 | try { 17 | delay(Long.MAX_VALUE) 18 | } finally { 19 | println("Child is cancelled") 20 | } 21 | } 22 | yield() 23 | println("Cancelling child") 24 | child.cancel() 25 | child.join() 26 | yield() 27 | println("Parent is not cancelled") 28 | } 29 | job.join() 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-exceptions-04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | fun main() = runBlocking { 11 | val handler = CoroutineExceptionHandler { _, exception -> 12 | println("CoroutineExceptionHandler got $exception") 13 | } 14 | val job = GlobalScope.launch(handler) { 15 | launch { // the first child 16 | try { 17 | delay(Long.MAX_VALUE) 18 | } finally { 19 | withContext(NonCancellable) { 20 | println("Children are cancelled, but exception is not handled until all children terminate") 21 | delay(100) 22 | println("The first child finished its non cancellable block") 23 | } 24 | } 25 | } 26 | launch { // the second child 27 | delay(10) 28 | println("Second child throws an exception") 29 | throw ArithmeticException() 30 | } 31 | } 32 | job.join() 33 | } 34 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-exceptions-05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import java.io.IOException 10 | 11 | fun main() = runBlocking { 12 | val handler = CoroutineExceptionHandler { _, exception -> 13 | println("CoroutineExceptionHandler got $exception with suppressed ${exception.suppressed.contentToString()}") 14 | } 15 | val job = GlobalScope.launch(handler) { 16 | launch { 17 | try { 18 | delay(Long.MAX_VALUE) // it gets cancelled when another sibling fails with IOException 19 | } finally { 20 | throw ArithmeticException() // the second exception 21 | } 22 | } 23 | launch { 24 | delay(100) 25 | throw IOException() // the first exception 26 | } 27 | delay(Long.MAX_VALUE) 28 | } 29 | job.join() 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-exceptions-06.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import java.io.IOException 10 | 11 | fun main() = runBlocking { 12 | val handler = CoroutineExceptionHandler { _, exception -> 13 | println("CoroutineExceptionHandler got $exception") 14 | } 15 | val job = GlobalScope.launch(handler) { 16 | val inner = launch { // all this stack of coroutines will get cancelled 17 | launch { 18 | launch { 19 | throw IOException() // the original exception 20 | } 21 | } 22 | } 23 | try { 24 | inner.join() 25 | } catch (e: CancellationException) { 26 | println("Rethrowing CancellationException with original cause") 27 | throw e // cancellation exception is rethrown, yet the original IOException gets to the handler 28 | } 29 | } 30 | job.join() 31 | } 32 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-1.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | fun main() { 9 | 10 | withoutSequence() 11 | 12 | withSequence() 13 | } 14 | 15 | private fun withoutSequence() { 16 | val result = listOf("a", "b", "ac", "d", "e", "f", "g", "h", "i", "j", "ak") 17 | .filter { 18 | println("filter: $it") 19 | it.startsWith("a", ignoreCase = true) 20 | } 21 | .map { 22 | println("map: $it") 23 | it.toUpperCase() 24 | } 25 | .take(2) 26 | .toList() 27 | 28 | println("size: ${result.size}") 29 | } 30 | 31 | private fun withSequence() { 32 | val result = listOf("a", "b", "ac", "d", "e", "f", "g", "h", "i", "j", "ak") 33 | .asSequence() 34 | .filter { 35 | println("filter: $it") 36 | it.startsWith("a", ignoreCase = true) 37 | } 38 | .map { 39 | println("map: $it") 40 | it.toUpperCase() 41 | } 42 | .take(2) 43 | .toList() 44 | 45 | println("size: ${result.size}") 46 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10a.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.asFlow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.transform 12 | import kotlinx.coroutines.runBlocking 13 | 14 | suspend fun performRequest9(request: Int): String { 15 | delay(1000) // imitate long-running asynchronous work 16 | return "response $request" 17 | } 18 | 19 | fun main() = runBlocking { 20 | (1..3).asFlow() // a flow of requests 21 | .transform { request -> 22 | emit("Making request $request") 23 | emit(performRequest9(request)) 24 | } 25 | .collect { response -> println(response) } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-10b.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.flow.flow 11 | import kotlinx.coroutines.flow.take 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun numbers(): Flow = flow { 15 | try { 16 | emit(1) 17 | emit(2) 18 | println("This line will not execute") 19 | emit(3) 20 | } catch (ex: Exception) { 21 | println(ex.message) 22 | } finally { 23 | println("Finally in numbers") 24 | } 25 | } 26 | 27 | fun main() = runBlocking { 28 | numbers() 29 | .take(2) // take only the first two 30 | .collect { value -> println(value) } 31 | } 32 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-11.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.asFlow 9 | import kotlinx.coroutines.flow.map 10 | import kotlinx.coroutines.flow.reduce 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | val sum1 = (1..5).asFlow() 15 | .reduce { a, b -> 16 | println("$a + $b = ${a + b}") 17 | a + b 18 | } // sum them (terminal operator) 19 | println(sum1) 20 | 21 | println("----") 22 | 23 | val sum2 = (1..5).asFlow() 24 | .map { it * it } // squares of numbers from 1 to 5 25 | .reduce { a, b -> 26 | println("$a + $b = ${a + b}") 27 | a + b 28 | } // sum them (terminal operator) 29 | println(sum2) 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-12.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.asFlow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.flow.filter 11 | import kotlinx.coroutines.flow.map 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun main() = runBlocking { 15 | (1..5).asFlow() 16 | .filter { 17 | println("Filter $it") 18 | it % 2 == 0 19 | } 20 | .map { 21 | println("Map $it") 22 | "string $it" 23 | }.collect { 24 | println("Collect $it") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-13.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.flow.flow 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun log13(msg: String) = println("[${Thread.currentThread().name}] $msg") 14 | 15 | fun foo13(): Flow = flow { 16 | for (i in 1..3) { 17 | emit(i) 18 | } 19 | } 20 | 21 | fun main() = runBlocking { 22 | log13("Started foo flow") 23 | foo13().collect { value -> log13("Collected $value") } 24 | } 25 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-14.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun foo14(): Flow = flow { 15 | // The WRONG way to change context for CPU-consuming code in flow builder 16 | kotlinx.coroutines.withContext(Dispatchers.Default) { 17 | for (i in 1..3) { 18 | Thread.sleep(100) // pretend we are computing it in CPU-consuming way 19 | emit(i) // emit next value 20 | } 21 | } 22 | } 23 | 24 | fun main() = runBlocking { 25 | foo14().collect { value -> println(value) } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-15-flowOn.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.flow.flowOn 13 | import kotlinx.coroutines.runBlocking 14 | 15 | fun log15(msg: String) = println("[${Thread.currentThread().name}] $msg") 16 | 17 | fun foo15(): Flow = flow { 18 | for (i in 1..3) { 19 | Thread.sleep(100) // pretend we are computing it in CPU-consuming way 20 | log("Emitting $i") 21 | emit(i) // emit next value 22 | } 23 | }.flowOn(Dispatchers.Default) // RIGHT way to change context for CPU-consuming code in flow builder 24 | 25 | fun main() = runBlocking { 26 | foo15().collect { value -> 27 | log("Collected $value") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-16.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.runBlocking 13 | import kotlin.system.measureTimeMillis 14 | 15 | fun foo16(): Flow = flow { 16 | for (i in 1..3) { 17 | delay(100) // pretend we are asynchronously waiting 100 ms 18 | emit(i) // emit next value 19 | } 20 | } 21 | 22 | fun main() = runBlocking { 23 | val time = measureTimeMillis { 24 | foo16().collect { value -> 25 | delay(300) // pretend we are processing it for 300 ms 26 | println(value) 27 | } 28 | } 29 | println("Collected in $time ms") 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-1-without-buffer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.runBlocking 13 | import kotlin.system.measureTimeMillis 14 | 15 | fun foo17_3(): Flow = flow { 16 | for (i in 1..3) { 17 | println("- value : $i - inside flow. delaying 1 second") 18 | delay(1000) // pretend we are asynchronously waiting 100 ms 19 | println("- value : $i - inside flow. Emitting") 20 | emit(i) // emit next value 21 | } 22 | } 23 | 24 | fun main() = runBlocking { 25 | val time = measureTimeMillis { 26 | foo17_3() 27 | .collect { value -> 28 | println("- value : $value - inside collect. delaying 5 second") 29 | delay(5000) // pretend we are processing it for 300 ms 30 | println("- value : $value - inside collect. completed") 31 | } 32 | } 33 | println("Collected in $time ms") 34 | } 35 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-17-3-buffer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.buffer 11 | import kotlinx.coroutines.flow.collect 12 | import kotlinx.coroutines.flow.flow 13 | import kotlinx.coroutines.runBlocking 14 | import kotlin.system.measureTimeMillis 15 | 16 | fun foo17_1(): Flow = flow { 17 | for (i in 1..3) { 18 | delay(100) // pretend we are asynchronously waiting 100 ms 19 | emit(i) // emit next value 20 | } 21 | } 22 | 23 | fun main() = runBlocking { 24 | val time = measureTimeMillis { 25 | foo17_1() 26 | .buffer() // buffer emissions, don't wait 27 | .collect { value -> 28 | delay(300) // pretend we are processing it for 300 ms 29 | println(value) 30 | } 31 | } 32 | println("Collected in $time ms") 33 | } 34 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-19-collectLatest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collectLatest 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.runBlocking 13 | import kotlin.system.measureTimeMillis 14 | 15 | 16 | fun foo19(): Flow = flow { 17 | for (i in 1..3) { 18 | println("- value : $i - inside flow. delaying 1 second") 19 | delay(1000) // pretend we are asynchronously waiting 100 ms 20 | println("- value : $i - inside flow. Emitting") 21 | emit(i) // emit next value 22 | } 23 | } 24 | 25 | fun main() = runBlocking { 26 | val time = measureTimeMillis { 27 | foo19() 28 | .collectLatest { value -> 29 | println("- value : $value - inside collect. delaying 5 second") 30 | delay(5000) // pretend we are processing it for 300 ms 31 | println("- value : $value - inside collect. completed") 32 | } 33 | } 34 | println("Collected in $time ms") 35 | } 36 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-2.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | fun main() { 9 | 10 | val seqFromChunks = sequence { 11 | yield(1) 12 | println("test 1") 13 | yieldAll((2..5).toList()) 14 | println("test 2") // this line and the below lines is not executed. 15 | yield(6) 16 | 17 | yieldAll(listOf(7, 8, 9)) 18 | yieldAll(generateSequence(10) { it + 2 }) 19 | } 20 | 21 | println(seqFromChunks.take(5).toList()) 22 | 23 | println("---------------------------------") 24 | 25 | val seqFromChunks2 = sequence { 26 | yield(1) 27 | println("test 1") 28 | yieldAll((2..5).toList()) 29 | println("test 2") 30 | yield(6) 31 | 32 | yieldAll(listOf(7, 8, 9)) 33 | println("test 3") 34 | yieldAll(generateSequence(10) { it + 2 }) 35 | println("test 4") // this line is not executed. 36 | } 37 | 38 | println(seqFromChunks2.take(10).toList()) 39 | } 40 | 41 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-onEach.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.* 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun foo20(): Flow = flow { 13 | for (i in 1..3) { 14 | delay(1000) 15 | emit(i) 16 | } 17 | } 18 | 19 | fun main() = runBlocking { 20 | 21 | val numbersFlow = (1..3).asFlow().onEach { delay(1000) } // flow of numbers 1,2,3 22 | 23 | numbersFlow 24 | .collect { 25 | println(it) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-20-zip.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.asFlow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.flow.flowOf 11 | import kotlinx.coroutines.flow.zip 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun main() = runBlocking { 15 | 16 | val numbersFlow = (1..3).asFlow() // flow of numbers 1,2,3 17 | val stringsFlow = flowOf("one", "two", "three") // flow of strings 18 | 19 | numbersFlow.zip(stringsFlow) { a, b -> 20 | "$a -> $b" 21 | } // compose a single string 22 | .collect { 23 | println(it) 24 | } // collect and print 25 | } 26 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-21-zip.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.* 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | val nums = (1..3).asFlow().onEach { 14 | println("1st flow. value : $it") 15 | delay(100) 16 | } // numbers 1..3 every 100 ms 17 | val strs = flowOf("one", "two", "three").onEach { 18 | println("2nd flow. value : $it") 19 | delay(4000) 20 | } // strings every 4000 ms 21 | 22 | val startTime = System.currentTimeMillis() // remember the start time 23 | 24 | nums.zip(strs) { a, b -> "$a -> $b" } // compose a single string with "zip" 25 | .map { 26 | println("Applying map for : $it") 27 | it 28 | } 29 | .collect { value -> // collect and print 30 | println("$value at ${System.currentTimeMillis() - startTime} ms from start") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-1.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.* 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | val nums = (1..3).asFlow().onEach { 14 | println("1st flow. value : $it") 15 | delay(100) 16 | } // numbers 1..3 every 300 ms 17 | val strs = flowOf("one", "two", "three").onEach { 18 | println("2nd flow. value : $it") 19 | delay(4000) 20 | } // strings every 400 ms 21 | val startTime = System.currentTimeMillis() // remember the start time 22 | 23 | nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine" 24 | .collect { value -> // collect and print 25 | println("$value at ${System.currentTimeMillis() - startTime} ms from start") 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-22-combine-2.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | 9 | import kotlinx.coroutines.delay 10 | import kotlinx.coroutines.flow.* 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun main() = runBlocking { 14 | val nums = (1..3).asFlow().onEach { delay(300) } // numbers 1..3 every 300 ms 15 | val strs = flowOf("one", "two", "three").onEach { delay(400) } // strings every 400 ms 16 | val startTime = System.currentTimeMillis() // remember the start time 17 | nums.combine(strs) { a, b -> "$a -> $b" } // compose a single string with "combine" 18 | .collect { value -> // collect and print 19 | println("$value at ${System.currentTimeMillis() - startTime} ms from start") 20 | } 21 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-23-flatMapConcat.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.* 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun requestFlow23(i: Int): Flow = flow { 13 | emit("$i: First") 14 | delay(5000) // wait 500 ms 15 | emit("$i: Second") 16 | } 17 | 18 | fun main() = runBlocking { 19 | val startTime = System.currentTimeMillis() // remember the start time 20 | 21 | (1..3).asFlow().onEach { delay(100) } // a number every 100 ms 22 | .flatMapConcat { requestFlow23(it) } 23 | .collect { value -> // collect and print 24 | println("$value at ${System.currentTimeMillis() - startTime} ms from start") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-24-flatMapMerge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.* 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun requestFlow24(i: Int): Flow = flow { 13 | emit("$i: First") 14 | delay(5000) // wait 500 ms 15 | emit("$i: Second") 16 | } 17 | 18 | fun main() = runBlocking { 19 | val startTime = System.currentTimeMillis() // remember the start time 20 | 21 | (1..3).asFlow().onEach { delay(100) } // a number every 100 ms 22 | .flatMapMerge { requestFlow24(it) } 23 | .collect { value -> // collect and print 24 | println("$value at ${System.currentTimeMillis() - startTime} ms from start") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-25-flatMapLatest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.* 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun requestFlow(i: Int): Flow = flow { 13 | emit("$i: First") 14 | delay(5000) // wait 500 ms 15 | emit("$i: Second") 16 | } 17 | 18 | fun main() = runBlocking { 19 | val startTime = System.currentTimeMillis() // remember the start time 20 | 21 | (1..3).asFlow().onEach { delay(100) } // a number every 100 ms 22 | .flatMapLatest { requestFlow(it) } 23 | .collect { value -> // collect and print 24 | println("$value at ${System.currentTimeMillis() - startTime} ms from start") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-26-handle-exceptions-strategy-1.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.flow.flow 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun foo26(): Flow = flow { 14 | for (i in 1..3) { 15 | println("Emitting $i") 16 | emit(i) // emit next value 17 | } 18 | } 19 | 20 | fun main() = runBlocking { 21 | try { 22 | foo26().collect { value -> 23 | println(value) 24 | check(value <= 1) { "Collected $value" } 25 | } 26 | } catch (e: Throwable) { 27 | println("Caught $e") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-27-handle-exceptions-strategy-1.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.flow.flow 11 | import kotlinx.coroutines.flow.map 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun foo27(): Flow = 15 | flow { 16 | for (i in 1..3) { 17 | println("Emitting $i") 18 | emit(i) // emit next value 19 | } 20 | } 21 | .map { value -> 22 | check(value <= 1) { "Crashed on $value" } 23 | "string $value" 24 | } 25 | 26 | fun main() = runBlocking { 27 | try { 28 | foo27().collect { value -> println(value) } 29 | } catch (e: Throwable) { 30 | println("Caught $e") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-28-handle-exceptions-strategy-2.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.* 9 | import kotlinx.coroutines.runBlocking 10 | 11 | fun foo28(): Flow = 12 | flow { 13 | for (i in 1..3) { 14 | println("Emitting $i") 15 | emit(i) // emit next value 16 | } 17 | } 18 | .map { value -> 19 | check(value <= 1) { "Crashed on $value" } 20 | "string $value" 21 | } 22 | 23 | fun main() = runBlocking { 24 | foo28() 25 | .catch { e -> emit("Caught $e") } // emit on exception 26 | .collect { value -> println(value) } 27 | } 28 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-29-handle-exceptions-strategy-2.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.catch 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun foo29(): Flow = flow { 15 | for (i in 1..3) { 16 | println("Emitting $i") 17 | emit(i) 18 | } 19 | } 20 | 21 | fun main() = runBlocking { 22 | foo29() 23 | .catch { e -> println("Caught $e") } // does not catch downstream exceptions 24 | .collect { value -> 25 | check(value <= 1) { "Collected $value" } 26 | println(value) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-3.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.runBlocking 10 | 11 | fun main() { 12 | foo2().forEach { value -> println(value) } 13 | 14 | runBlocking { 15 | foo3().forEach { value -> println(value) } 16 | } 17 | } 18 | 19 | fun foo2(): Sequence = sequence { // sequence builder 20 | for (i in 1..3) { 21 | Thread.sleep(1000) // pretend we are computing it 22 | yield(i) // yield next value 23 | } 24 | } 25 | 26 | 27 | suspend fun foo3(): List { 28 | delay(1000) // pretend we are doing something asynchronous here 29 | return listOf(1, 2, 3) 30 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-30-handle-exceptions-strategy-2.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.* 9 | import kotlinx.coroutines.runBlocking 10 | 11 | fun foo30(): Flow = flow { 12 | for (i in 1..3) { 13 | println("Emitting $i") 14 | emit(i) 15 | } 16 | } 17 | 18 | fun main() = runBlocking { 19 | foo30() 20 | .onEach { value -> 21 | check(value <= 1) { "Collected $value" } 22 | println(value) 23 | } 24 | .catch { e -> println("Caught $e") } 25 | .collect() 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-1.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.asFlow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun foo31a(): Flow = (1..3).asFlow() 14 | 15 | fun main() = runBlocking { 16 | try { 17 | foo31a().collect { value -> println(value) } 18 | } finally { 19 | println("Done") 20 | } 21 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-31-finally-2.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.flow.flow 11 | import kotlinx.coroutines.runBlocking 12 | 13 | fun foo31b(): Flow = flow { 14 | for (i in 1..3) { 15 | println("Emitting $i") 16 | emit(i) // emit next value 17 | } 18 | } 19 | 20 | fun main() = runBlocking { 21 | try { 22 | foo31b().collect { value -> 23 | println(value) 24 | check(value <= 1) { "Collected $value" } 25 | } 26 | } catch (e: Throwable) { 27 | println("Caught $e") 28 | } finally { 29 | println("done") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-32-onCompletion.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.asFlow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.onCompletion 12 | import kotlinx.coroutines.runBlocking 13 | 14 | fun foo32(): Flow = (1..3).asFlow() 15 | 16 | fun main() = runBlocking { 17 | foo32() 18 | .onCompletion { println("Done") } 19 | .collect { value -> println(value) } 20 | } 21 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-33-onCompletion-and-catch.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.* 9 | import kotlinx.coroutines.runBlocking 10 | 11 | fun foo33(): Flow = flow { 12 | for (i in 1..3) { 13 | emit(i) 14 | } 15 | } 16 | 17 | fun main() = runBlocking { 18 | foo33() 19 | .onEach { 20 | check(it <= 1) { "Collected $it" } 21 | } 22 | .onCompletion { cause -> if (cause != null) println("Flow completed exceptionally - $cause") } 23 | .catch { cause -> println("Caught exception - $cause") } 24 | .collect { value -> println(value) } 25 | } 26 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-34-onCompletion-and-catch.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.* 9 | import kotlinx.coroutines.runBlocking 10 | 11 | fun foo34(): Flow = (1..3).asFlow() 12 | 13 | fun main() = runBlocking { 14 | foo34() 15 | .onCompletion { cause -> println("Flow completed with $cause") } 16 | .catch { cause -> println("Caught exception - $cause") } // cannot catch downstream exceptions 17 | .collect { value -> 18 | check(value <= 1) { "Collected $value" } 19 | println(value) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-35-collect-is-suspending.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.asFlow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.onEach 12 | import kotlinx.coroutines.runBlocking 13 | 14 | 15 | fun main() = runBlocking { 16 | (1..3).asFlow().onEach { delay(10000) } 17 | .onEach { event -> println("Event: $event") } 18 | .collect() // <--- Collecting the flow waits 19 | println("Done") 20 | } 21 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-36-launchIn-is-fire-and-forget.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.asFlow 10 | import kotlinx.coroutines.flow.launchIn 11 | import kotlinx.coroutines.flow.onEach 12 | import kotlinx.coroutines.runBlocking 13 | 14 | 15 | fun main() = runBlocking { 16 | (1..3).asFlow().onEach { delay(100) } 17 | .onEach { event -> println("Event: $event") } 18 | .launchIn(this) // <--- Launching the flow in a separate coroutine 19 | println("Done") 20 | } 21 | 22 | 23 | /* 24 | launchIn() is a shorthand for 25 | scope.launch{ 26 | flow.collect() 27 | } 28 | * */ -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-37-launchIn-is-like-this.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.asFlow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.onEach 12 | import kotlinx.coroutines.launch 13 | import kotlinx.coroutines.runBlocking 14 | 15 | fun main() = runBlocking { 16 | launch { 17 | (1..3).asFlow().onEach { delay(100) } 18 | .onEach { event -> println("Event: $event") } 19 | .collect() // <--- Launching the flow in a separate coroutine 20 | } 21 | println("Done") 22 | } 23 | 24 | /* 25 | launchIn() is a shorthand for 26 | scope.launch{ 27 | flow.collect() 28 | } 29 | * */ -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-38-flow-builder-does-cancellation-check.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.cancel 4 | import kotlinx.coroutines.flow.Flow 5 | import kotlinx.coroutines.flow.collect 6 | import kotlinx.coroutines.flow.flow 7 | import kotlinx.coroutines.runBlocking 8 | 9 | /* 10 | flow builder 11 | flow { 12 | ... 13 | } 14 | performs additional ensureActive checks for cancellation on each emitted value. 15 | * */ 16 | 17 | fun foo(): Flow = flow { 18 | for (i in 1..5) { 19 | println("Emitting $i") 20 | emit(i) 21 | } 22 | } 23 | 24 | fun main() = runBlocking { 25 | foo().collect { value -> 26 | if (value == 3) cancel() 27 | println(value) 28 | } 29 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-39-asFlow-operator-doesnt-do-cancellation-check.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.cancel 4 | import kotlinx.coroutines.flow.asFlow 5 | import kotlinx.coroutines.flow.collect 6 | import kotlinx.coroutines.runBlocking 7 | 8 | /* 9 | Many flow operators don't do cancellation check for performance reasons. 10 | For example, asFlow() doesn't do cancellation check. 11 | * */ 12 | 13 | fun main() = runBlocking { 14 | (1..5).asFlow().collect { value -> 15 | if (value == 3) cancel() 16 | println(value) 17 | } 18 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-4.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.delay 4 | import kotlinx.coroutines.flow.collect 5 | import kotlinx.coroutines.flow.flow 6 | import kotlinx.coroutines.runBlocking 7 | 8 | /* 9 | * Since collect() is a suspending function, it can only be called from a coroutine or another suspending function. 10 | * This is why you wrap the code with runBlocking(). 11 | * */ 12 | fun main() { 13 | val namesFlow = flow { 14 | val names = listOf("Jody", "Steve", "Lance", "Joe") 15 | for (name in names) { 16 | delay(1000) 17 | emit(name) 18 | } 19 | } 20 | 21 | runBlocking { 22 | namesFlow.collect { println(it) } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-40-make-asFlow-cancellable-way-1.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.cancel 4 | import kotlinx.coroutines.flow.asFlow 5 | import kotlinx.coroutines.flow.cancellable 6 | import kotlinx.coroutines.flow.collect 7 | import kotlinx.coroutines.runBlocking 8 | 9 | /* 10 | Many flow operators don't do cancellation check for performance reasons. 11 | For example, asFlow() doesn't do cancellation check. 12 | asFlow().cancellable() makes asFlow() cancellable. 13 | * */ 14 | 15 | fun main() = runBlocking { 16 | (1..5).asFlow().cancellable().collect { value -> 17 | if (value == 3) cancel() 18 | println(value) 19 | } 20 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-41-make-asFlow-cancellable-way-2.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.cancel 4 | import kotlinx.coroutines.currentCoroutineContext 5 | import kotlinx.coroutines.ensureActive 6 | import kotlinx.coroutines.flow.asFlow 7 | import kotlinx.coroutines.flow.collect 8 | import kotlinx.coroutines.flow.onEach 9 | import kotlinx.coroutines.runBlocking 10 | 11 | /* 12 | Many flow operators don't do cancellation check for performance reasons. 13 | For example, asFlow() doesn't do cancellation check. 14 | Before each emission, checking ensureActive() makes asFlow() cancellable. 15 | 16 | * */ 17 | 18 | fun main() = runBlocking { 19 | (1..5).asFlow().onEach { currentCoroutineContext().ensureActive() } 20 | .collect { value -> 21 | if (value == 3) cancel() 22 | println(value) 23 | } 24 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-5.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.runBlocking 13 | 14 | /* 15 | * To get all the values in the stream as they're emitted, use collect() 16 | * */ 17 | 18 | fun main() = runBlocking { 19 | println("Calling foo...") 20 | val flow = foo5() 21 | 22 | println("Calling collect...") 23 | flow.collect { value -> println(value) } 24 | 25 | println("Calling collect again...") 26 | flow.collect { value -> println(value) } 27 | } 28 | 29 | fun foo5(): Flow = flow { 30 | println("Flow started") 31 | for (i in 1..3) { 32 | delay(100) 33 | emit(i) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-6.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.launch 13 | import kotlinx.coroutines.runBlocking 14 | 15 | fun foo6(): Flow = flow { // flow builder 16 | for (i in 1..3) { 17 | delay(100) // pretend we are doing something useful here 18 | emit(i) // emit next value 19 | } 20 | } 21 | 22 | fun main() = runBlocking { 23 | // Launch a concurrent coroutine to check if the main thread is blocked 24 | launch { 25 | for (k in 1..3) { 26 | println("I'm not blocked $k") 27 | delay(100) 28 | } 29 | } 30 | 31 | // Collect the flow 32 | foo6().collect { value -> println(value) } 33 | println("end") 34 | } 35 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-7.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.runBlocking 13 | import kotlinx.coroutines.withTimeoutOrNull 14 | 15 | fun foo61(): Flow = flow { 16 | for (i in 1..3) { 17 | delay(100) 18 | println("Emitting $i") 19 | emit(i) 20 | } 21 | } 22 | 23 | fun main() = runBlocking { 24 | withTimeoutOrNull(250) { // Timeout after 250ms 25 | foo61().collect { value -> println(value) } 26 | } 27 | println("Done") 28 | } 29 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-8.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.flow.asFlow 9 | import kotlinx.coroutines.flow.collect 10 | import kotlinx.coroutines.runBlocking 11 | 12 | fun main() = runBlocking { 13 | // Convert an integer range to a flow 14 | (1..3).asFlow().collect { value -> println(value) } 15 | } 16 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-flow-9.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from flow.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.flow.asFlow 10 | import kotlinx.coroutines.flow.collect 11 | import kotlinx.coroutines.flow.map 12 | import kotlinx.coroutines.runBlocking 13 | 14 | suspend fun performRequest8(request: Int): String { 15 | delay(1000) // imitate long-running asynchronous work 16 | return "response $request" 17 | } 18 | 19 | fun main() = runBlocking { 20 | (1..3).asFlow() // a flow of requests 21 | .map { request -> performRequest8(request) } 22 | .collect { response -> println(response) } 23 | } 24 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-select-04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from select-expression.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import kotlinx.coroutines.selects.select 10 | import java.util.* 11 | 12 | fun CoroutineScope.asyncString(time: Int) = async { 13 | delay(time.toLong()) 14 | "Waited for $time ms" 15 | } 16 | 17 | fun CoroutineScope.asyncStringsList(): List> { 18 | val random = Random(3) 19 | return List(12) { asyncString(random.nextInt(1000)) } 20 | } 21 | 22 | fun main() = runBlocking { 23 | val list = asyncStringsList() 24 | val result = select { 25 | list.withIndex().forEach { (index, deferred) -> 26 | deferred.onAwait { answer -> 27 | "Deferred $index produced answer '$answer'" 28 | } 29 | } 30 | } 31 | println(result) 32 | val countActive = list.count { it.isActive } 33 | println("$countActive coroutines are still active") 34 | } 35 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-supervision-02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | 10 | fun main() = runBlocking { 11 | try { 12 | supervisorScope { 13 | val child = launch { 14 | try { 15 | println("Child is sleeping") 16 | delay(Long.MAX_VALUE) 17 | } finally { 18 | println("Child is cancelled") 19 | } 20 | } 21 | // Give our child a chance to execute and print using yield 22 | yield() 23 | println("Throwing exception from scope") 24 | throw AssertionError() 25 | } 26 | } catch (e: AssertionError) { 27 | println("Caught assertion error") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-supervision-03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from exception-handling.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.CoroutineExceptionHandler 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.runBlocking 11 | import kotlinx.coroutines.supervisorScope 12 | 13 | fun main() = runBlocking { 14 | val handler = CoroutineExceptionHandler { _, exception -> 15 | println("CoroutineExceptionHandler got $exception") 16 | } 17 | supervisorScope { 18 | val child = launch(handler) { 19 | println("Child throws an exception") 20 | throw AssertionError() 21 | } 22 | println("Scope is completing") 23 | } 24 | println("Scope is completed") 25 | } 26 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-sync-01.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from shared-mutable-state-and-concurrency.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import kotlin.system.measureTimeMillis 10 | 11 | suspend fun massiveRun1(action: suspend () -> Unit) { 12 | val n = 100 // number of coroutines to launch 13 | val k = 1000 // times an action is repeated by each coroutine 14 | val time = measureTimeMillis { 15 | coroutineScope { // scope for coroutines 16 | repeat(n) { 17 | launch { 18 | repeat(k) { action() } 19 | } 20 | } 21 | } 22 | } 23 | println("Completed ${n * k} actions in $time ms") 24 | } 25 | 26 | var counter1 = 0 27 | 28 | fun main() = runBlocking { 29 | withContext(Dispatchers.Default) { 30 | massiveRun1 { 31 | counter1++ 32 | } 33 | } 34 | println("Counter = $counter1") 35 | } 36 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-sync-02.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from shared-mutable-state-and-concurrency.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import kotlin.system.measureTimeMillis 10 | 11 | suspend fun massiveRun2(action: suspend () -> Unit) { 12 | val n = 100 // number of coroutines to launch 13 | val k = 1000 // times an action is repeated by each coroutine 14 | val time = measureTimeMillis { 15 | coroutineScope { // scope for coroutines 16 | repeat(n) { 17 | launch { 18 | repeat(k) { action() } 19 | } 20 | } 21 | } 22 | } 23 | println("Completed ${n * k} actions in $time ms") 24 | } 25 | 26 | @Volatile // in Kotlin `volatile` is an annotation 27 | var counter2 = 0 28 | 29 | fun main() = runBlocking { 30 | withContext(Dispatchers.Default) { 31 | massiveRun2 { 32 | counter2++ 33 | } 34 | } 35 | println("Counter = $counter2") 36 | } 37 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-sync-03.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from shared-mutable-state-and-concurrency.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import java.util.concurrent.atomic.AtomicInteger 10 | import kotlin.system.measureTimeMillis 11 | 12 | suspend fun massiveRun3(action: suspend () -> Unit) { 13 | val n = 100 // number of coroutines to launch 14 | val k = 1000 // times an action is repeated by each coroutine 15 | val time = measureTimeMillis { 16 | coroutineScope { // scope for coroutines 17 | repeat(n) { 18 | launch { 19 | repeat(k) { action() } 20 | } 21 | } 22 | } 23 | } 24 | println("Completed ${n * k} actions in $time ms") 25 | } 26 | 27 | val counter3 = AtomicInteger() 28 | 29 | fun main() = runBlocking { 30 | withContext(Dispatchers.Default) { 31 | massiveRun3 { 32 | counter3.incrementAndGet() 33 | } 34 | } 35 | println("Counter = $counter3") 36 | } 37 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-sync-04.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from shared-mutable-state-and-concurrency.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import kotlin.system.measureTimeMillis 10 | 11 | suspend fun massiveRun4(action: suspend () -> Unit) { 12 | val n = 100 // number of coroutines to launch 13 | val k = 1000 // times an action is repeated by each coroutine 14 | val time = measureTimeMillis { 15 | coroutineScope { // scope for coroutines 16 | repeat(n) { 17 | launch { 18 | repeat(k) { action() } 19 | } 20 | } 21 | } 22 | } 23 | println("Completed ${n * k} actions in $time ms") 24 | } 25 | 26 | val counterContext4 = newSingleThreadContext("CounterContext") 27 | var counter4 = 0 28 | 29 | fun main() = runBlocking { 30 | withContext(Dispatchers.Default) { 31 | massiveRun4 { 32 | // confine each increment to a single-threaded context 33 | withContext(counterContext4) { 34 | counter4++ 35 | } 36 | } 37 | } 38 | println("Counter = $counter4") 39 | } 40 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/example-sync-05.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 | */ 4 | 5 | // This file was automatically generated from shared-mutable-state-and-concurrency.md by Knit tool. Do not edit. 6 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 7 | 8 | import kotlinx.coroutines.* 9 | import kotlin.system.measureTimeMillis 10 | 11 | suspend fun massiveRun5(action: suspend () -> Unit) { 12 | val n = 100 // number of coroutines to launch 13 | val k = 1000 // times an action is repeated by each coroutine 14 | val time = measureTimeMillis { 15 | coroutineScope { // scope for coroutines 16 | repeat(n) { 17 | launch { 18 | repeat(k) { action() } 19 | } 20 | } 21 | } 22 | } 23 | println("Completed ${n * k} actions in $time ms") 24 | } 25 | 26 | val counterContext5 = newSingleThreadContext("CounterContext") 27 | var counter5 = 0 28 | 29 | fun main() = runBlocking { 30 | // confine everything to a single-threaded context 31 | withContext(counterContext5) { 32 | massiveRun5 { 33 | counter5++ 34 | } 35 | } 36 | println("Counter = $counter5") 37 | } 38 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-01-coroutineScope.cancel().kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * 🐲 Cancellation of CoroutineScope 🐲 7 | * If you cancel a CoroutineScope, then all coroutines executing inside this scope is cancelled. 8 | * */ 9 | 10 | fun main() { 11 | cancelParentJob2() 12 | } 13 | 14 | fun cancelParentJob2() { 15 | val coroutineScope = CoroutineScope(Dispatchers.Unconfined) 16 | 17 | val job1 = coroutineScope.launch { 18 | delay(500) 19 | } 20 | val job2 = coroutineScope.launch { 21 | delay(500) 22 | } 23 | 24 | coroutineScope.cancel() 25 | 26 | println("Job 1 state: ${job1.status()}") 27 | println("Job 2 state: ${job2.status()}") 28 | println("Is coroutineScope active: ${coroutineScope.isActive}") 29 | } 30 | 31 | 32 | fun Job.status(): String = when { 33 | isCancelled -> "cancelled" 34 | isActive -> "Active" 35 | isCompleted -> "Complete" 36 | else -> "Nothing" 37 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-03-childJob.cancel().kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * 🤡Cancellation of child job🤡 7 | * 🔥 In this case, child job is cancelled, but other child jobs and parent job are still active and continue execution. 8 | * */ 9 | 10 | fun main() { 11 | 12 | val parentJob = Job() 13 | 14 | val coroutineScope = CoroutineScope(Dispatchers.IO + parentJob) 15 | 16 | var child1: Job? = null 17 | var child2: Job? = null 18 | 19 | 20 | coroutineScope.launch { 21 | child1 = launch { 22 | delay(500) 23 | } 24 | child2 = launch { 25 | delay(500) 26 | } 27 | 28 | 29 | child1?.cancel() 30 | 31 | println("Job 1 state: ${child1?.status()}") 32 | println("Job 2 state: ${child2?.status()}") 33 | println("parentJob.isActive : ${parentJob.isActive}") 34 | println("coroutineScope.isActive : ${coroutineScope.isActive}") 35 | println("coroutineScope.isActive : $isActive") 36 | } 37 | 38 | 39 | Thread.sleep(2000L) 40 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-04-throw-exception-in-parent-Job.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * 💀Throw exception in parent job💀 7 | * 🔥 In this case, exception is thrown in the parent job, then all child jobs cancelled automatically. 8 | * */ 9 | 10 | fun main() { 11 | 12 | var child1: Job? = null 13 | var child2: Job? = null 14 | 15 | // Parent Job and Coroutine Exception Handler 16 | val parentJob = Job() 17 | 18 | val handler = CoroutineExceptionHandler { _, exception -> 19 | println("Caught $exception") 20 | println("Job 1 state: ${child1?.status()}") 21 | println("Job 2 state: ${child2?.status()}") 22 | println("Parent job is active: ${parentJob.isActive}") 23 | } 24 | 25 | // CoroutineScope 26 | val coroutineScope = CoroutineScope(Dispatchers.IO + parentJob + handler) 27 | 28 | 29 | // Use 30 | coroutineScope.launch { 31 | 32 | child1 = launch { 33 | delay(500) 34 | } 35 | child2 = launch { 36 | delay(500) 37 | } 38 | 39 | delay(200) 40 | throw RuntimeException() 41 | 42 | } 43 | 44 | 45 | Thread.sleep(2000L) 46 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-07-parentJob.cancel()-alternative-1.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * 7 | * 🤡 Cancellation of parent job with alternative way 1 🤡 8 | * 🔥 In this case, parent job is cancelled, then all child jobs cancelled automatically. 9 | * */ 10 | 11 | fun main() { 12 | 13 | // Parent Job and Coroutine Exception Handler 14 | val parentJob = Job() 15 | 16 | // CoroutineScope 17 | val coroutineScope = CoroutineScope(Dispatchers.IO + parentJob) 18 | 19 | var child1: Job? = null 20 | var child2: Job? = null 21 | 22 | // Use 23 | val currentJob = coroutineScope.launch { 24 | child1 = launch { 25 | delay(500) 26 | } 27 | child2 = launch { 28 | delay(500) 29 | } 30 | } 31 | 32 | Thread.sleep(300L) 33 | 34 | currentJob.cancel() 35 | 36 | println("Job 1 state: ${child1?.status()}") 37 | println("Job 2 state: ${child2?.status()}") 38 | println("Parent job is active: ${currentJob.isActive}") 39 | 40 | 41 | Thread.sleep(2000L) 42 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-08-parentJob.cancel()-alternative-2.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * 7 | * 🤡 Cancellation of parent job with alternative way 2 🤡 8 | * 🔥 In this case, parent job is cancelled, then all child jobs cancelled automatically. 9 | * */ 10 | 11 | fun main() { 12 | 13 | // CoroutineScope 14 | val coroutineScope = CoroutineScope(Dispatchers.IO) 15 | 16 | var child1: Job? = null 17 | var child2: Job? = null 18 | 19 | // Use 20 | val currentJob = coroutineScope.launch { 21 | child1 = launch { 22 | delay(500) 23 | } 24 | child2 = launch { 25 | delay(500) 26 | } 27 | } 28 | 29 | Thread.sleep(300L) 30 | 31 | currentJob.cancel() 32 | 33 | println("Job 1 state: ${child1?.status()}") 34 | println("Job 2 state: ${child2?.status()}") 35 | println("Parent job is active: ${currentJob.isActive}") 36 | 37 | Thread.sleep(2000L) 38 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-09-coroutineContext[Job].kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * 7 | * The coroutine's Job is part of its context, and can be retrieved from it using the coroutineContext[Job] expression: 8 | * println("My job is ${coroutineContext[Job]}") 9 | * 10 | * In the debug mode, it outputs something like this: 11 | * My job is "coroutine#1":BlockingCoroutine{Active}@6d311334 12 | * 13 | * To Enable the logging in IntelliJ toolbar menu: 14 | * Run -> Edit Configuration and add the following in VM options 15 | * -Dkotlinx.coroutines.debug 16 | * */ 17 | 18 | fun main() { 19 | 20 | // Parent Job and Coroutine Exception Handler 21 | val parentJob = Job() 22 | 23 | // CoroutineScope 24 | val coroutineScope = CoroutineScope(Dispatchers.IO + parentJob) 25 | 26 | 27 | coroutineScope.launch { 28 | coroutineScope.launch(CoroutineName("cocuk1")) { 29 | delay(500) 30 | println("My job is ${coroutineContext[Job]}") 31 | 32 | } 33 | coroutineScope.launch { 34 | delay(500) 35 | println("My job is ${coroutineContext[Job]}") 36 | } 37 | 38 | println("My job is ${coroutineContext[Job]}") 39 | 40 | 41 | } 42 | 43 | Thread.sleep(2000L) 44 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-11-invokeOnCompletion.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * usage of invokeOnCompletion 7 | * 8 | * You can call invokeOnCompletion() on a Job and register a lambda to be evaluated when the job is completed for any reason. 9 | * The parameter passed to the lambda will be: 10 | * 🏁 null if the job completed normally 11 | * 🚩 a CancellationException (or subclass) if the job was canceled 12 | * ‍☠ ️some other type of exception if the job failed 13 | * 14 | * https://klassbook.commonsware.com/lessons/Coroutine%20Basics/invokeOnCompletion.html 15 | * */ 16 | 17 | fun main() { 18 | 19 | val job = GlobalScope.launch(Dispatchers.IO) { 20 | withTimeout(2000L) { 21 | println("This is executed before the delay") 22 | stallForTime() 23 | println("This is executed after the delay") 24 | } 25 | } 26 | 27 | job.invokeOnCompletion { cause -> println("We were canceled due to ---> $cause <---") } 28 | 29 | println("This is executed immediately") 30 | 31 | Thread.sleep(5000) 32 | } 33 | 34 | suspend fun stallForTime() { 35 | withContext(Dispatchers.Default) { 36 | delay(10000L) 37 | } 38 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-12 - using try catch rather than supervisorJob.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.GlobalScope 4 | import kotlinx.coroutines.launch 5 | 6 | 7 | /* 8 | * try catch can be used rather then using SupervisorJob or SupervisorScope in order to prevent cancellation of other child jobs. 9 | * */ 10 | 11 | fun main() { 12 | 13 | /** 14 | * Exception is caught by try catch 15 | * */ 16 | GlobalScope.launch { 17 | try { 18 | println("1 - Throwing exception from launch") 19 | throw IndexOutOfBoundsException() 20 | println("1 - Unreached") 21 | } catch (e: IndexOutOfBoundsException) { 22 | println("1 - Caught IndexOutOfBoundsException") 23 | } 24 | } 25 | 26 | /* 27 | * Exception is thrown and crash occurs. 28 | * */ 29 | GlobalScope.launch { 30 | println("2 - Throwing exception from launch") 31 | throw Exception("ERROR!!!") 32 | println("2 - Unreached") 33 | } 34 | /*val deferred = GlobalScope.async { 35 | println("Throwing exception from async") 36 | throw ArithmeticException() 37 | println("Unreached") 38 | }*/ 39 | 40 | Thread.sleep(2000) 41 | } 42 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/jobs-16 - yield.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.delay 4 | import kotlinx.coroutines.launch 5 | import kotlinx.coroutines.runBlocking 6 | import kotlinx.coroutines.yield 7 | 8 | /* 9 | * Look at also the example-exceptions-03.kt 10 | * 11 | * 12 | * It temporarily deprioritises the current long running CPU task, giving other tasks(coroutines) a fair opportunity to run. 13 | * 14 | * If the work you’re doing is 1) CPU heavy, 2) may exhaust the thread pool and 3) you want to allow the thread to do other work without having to add more threads to the pool, then use yield(). 15 | * 16 | * */ 17 | 18 | fun main() = runBlocking { 19 | 20 | 21 | val job1 = launch { 22 | repeat(10) { 23 | delay(1000) 24 | println("$it. step done in job 1 ") 25 | yield() 26 | } 27 | } 28 | 29 | val job2 = launch { 30 | repeat(10) { 31 | delay(1000) 32 | println("$it. step done in job 2 ") 33 | yield() 34 | } 35 | } 36 | 37 | job1.join() 38 | job2.join() 39 | println("done") 40 | } 41 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-1.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.Dispatchers 2 | import kotlinx.coroutines.delay 3 | import kotlinx.coroutines.runBlocking 4 | import kotlinx.coroutines.withContext 5 | 6 | /** examples from resocoder */ 7 | fun main() { 8 | exampleWithContext() 9 | } 10 | 11 | fun exampleWithContext() = runBlocking { 12 | val startTime = System.currentTimeMillis() 13 | 14 | val result1 = withContext(Dispatchers.Default) { calculateHardThings(10) } 15 | println("1 done") 16 | val result2 = withContext(Dispatchers.IO) { calculateHardThings(20) } 17 | println("2 done") 18 | val result3 = withContext(Dispatchers.IO) { calculateHardThings(30) } 19 | println("3 done") 20 | 21 | val sum = result1 + result2 + result3 22 | println("async/await result = $sum") 23 | 24 | val endTime = System.currentTimeMillis() 25 | println("Time taken: ${endTime - startTime}") 26 | } 27 | 28 | suspend fun calculateHardThings(startNum: Int): Int { 29 | delay(1000) 30 | return startNum * 10 31 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-10-order-of-execution-.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.launch 4 | import kotlinx.coroutines.runBlocking 5 | 6 | fun main() = runBlocking { 7 | launch { 8 | println("5") 9 | } 10 | 11 | launch { 12 | println("6") 13 | } 14 | 15 | for (i in 7..10) { 16 | println(i.toString()) 17 | } 18 | 19 | launch { 20 | println("4") 21 | } 22 | 23 | launch { 24 | println("3") 25 | } 26 | 27 | for (i in 11..14) { 28 | println(i.toString()) 29 | } 30 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-3.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.async 2 | import kotlinx.coroutines.runBlocking 3 | 4 | /** examples from resocoder */ 5 | fun main() { 6 | exampleAsyncAwait1() 7 | exampleAsyncAwait2() 8 | } 9 | 10 | fun exampleAsyncAwait1() = runBlocking { 11 | val startTime = System.currentTimeMillis() 12 | 13 | val result1 = async { calculateHardThings(10) }.await() 14 | val result2 = async { calculateHardThings(20) }.await() 15 | val result3 = async { calculateHardThings(30) }.await() 16 | 17 | val sum = result1 + result2 + result3 18 | println("async/await result = $sum") 19 | 20 | val endTime = System.currentTimeMillis() 21 | println("Time taken: ${endTime - startTime}") 22 | } 23 | 24 | fun exampleAsyncAwait2() = runBlocking { 25 | val startTime = System.currentTimeMillis() 26 | 27 | val deferred1 = async { calculateHardThings(10) } 28 | val deferred2 = async { calculateHardThings(20) } 29 | val deferred3 = async { calculateHardThings(30) } 30 | 31 | val sum = deferred1.await() + deferred2.await() + deferred3.await() 32 | println("async/await result = $sum") 33 | 34 | val endTime = System.currentTimeMillis() 35 | println("Time taken: ${endTime - startTime}") 36 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-4.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.Dispatchers 2 | import kotlinx.coroutines.runBlocking 3 | 4 | /** examples from resocoder */ 5 | fun main() { 6 | exampleBlocking() 7 | exampleBlockingDispatcher() 8 | } 9 | 10 | 11 | fun exampleBlocking() = runBlocking { 12 | println("one") 13 | printlnDelayed("two") 14 | println("three") 15 | } 16 | 17 | // Running on another thread but still blocking the main thread 18 | fun exampleBlockingDispatcher() { 19 | runBlocking(Dispatchers.Default) { 20 | println("one - from thread ${Thread.currentThread().name}") 21 | printlnDelayed("two - from thread ${Thread.currentThread().name}") 22 | } 23 | // Outside of runBlocking to show that it's running in the blocked main thread 24 | println("three - from thread ${Thread.currentThread().name}") 25 | // It still runs only after the runBlocking is fully executed. 26 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-5.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.GlobalScope 2 | import kotlinx.coroutines.delay 3 | import kotlinx.coroutines.launch 4 | import kotlinx.coroutines.runBlocking 5 | 6 | /** examples from resocoder */ 7 | fun main() { 8 | exampleLaunchGlobal() 9 | exampleLaunchGlobalWaiting() 10 | } 11 | 12 | 13 | fun exampleLaunchGlobal() = runBlocking { 14 | println("one - from thread ${Thread.currentThread().name}") 15 | 16 | GlobalScope.launch { 17 | printlnDelayed("two - from thread ${Thread.currentThread().name}") 18 | } 19 | 20 | println("three - from thread ${Thread.currentThread().name}") 21 | delay(3000) 22 | } 23 | 24 | fun exampleLaunchGlobalWaiting() = runBlocking { 25 | println("one - from thread ${Thread.currentThread().name}") 26 | 27 | val job = GlobalScope.launch { 28 | printlnDelayed("two - from thread ${Thread.currentThread().name}") 29 | } 30 | 31 | println("three - from thread ${Thread.currentThread().name}") 32 | job.join() 33 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-6.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.Deferred 2 | import kotlinx.coroutines.async 3 | import kotlinx.coroutines.delay 4 | import kotlinx.coroutines.runBlocking 5 | 6 | /** To get the result from coroutine, you need to start the coroutine using async{ } 7 | * await() function awaits until the job is finished and gives you the result back 8 | * The last statement in the async block becomes your return statement. 9 | * */ 10 | fun main() { 11 | runBlocking { 12 | val deferredResult: Deferred = async { 13 | println("context of async : ${Thread.currentThread().name}") 14 | delay(3000L) 15 | "Veggie treat" 16 | } 17 | println("Your coke is ready, waiting for burger..") 18 | println("Here is your burger, ${deferredResult.await()}") 19 | println("--THE END--") 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-7-give-name-to-a-coroutine.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.CoroutineName 4 | import kotlinx.coroutines.Job 5 | import kotlinx.coroutines.launch 6 | import kotlinx.coroutines.runBlocking 7 | 8 | /** 9 | * 10 | * 1 - Give name to a coroutine -> CoroutineName("my-custom-name") 11 | * 2 - Print name of the coroutine -> Thread.currentThread().name - or - ${coroutineContext[Job]} 12 | * 13 | * To Enable the logging in IntelliJ toolbar menu: 14 | * Run -> Edit Configuration and add the following in VM options 15 | * -Dkotlinx.coroutines.debug 16 | * */ 17 | 18 | fun main() = runBlocking { 19 | println(Thread.currentThread().name) 20 | 21 | val job = launch(CoroutineName("my-custom-name")) { 22 | println(Thread.currentThread().name) 23 | println("${coroutineContext[Job]}") 24 | 25 | } 26 | 27 | job.join() 28 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-8-CoroutineStart.LAZY.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | import kotlinx.coroutines.* 4 | 5 | /** 6 | * 7 | * Calling start() on a coroutine that was started with CoroutineStart.LAZY causes the lazy flag to be removed. 8 | * At that point, the coroutine will be eligible to be executed. Exactly when it will be executed is up to the dispatcher and platform, and it will depend on what other coroutines exist and are running. 9 | * 10 | * https://klassbook.commonsware.com/lessons/Coroutine%20Basics/lazy-then-active.html 11 | * */ 12 | 13 | fun main() { 14 | val job = CoroutineScope(Dispatchers.IO).launch(start = CoroutineStart.LAZY) { 15 | stallForTime2() 16 | println("This is executed after the previous suspend fun stallForTime2 returns") 17 | } 18 | 19 | println("Before starting the job") 20 | job.start() 21 | println("After starting the job") 22 | Thread.sleep(5000) 23 | } 24 | 25 | suspend fun stallForTime2() { 26 | withContext(Dispatchers.Default) { 27 | delay(2000L) 28 | } 29 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/playground/random-practice-9-CoroutineStart.LAZY.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.playground 2 | 3 | 4 | import kotlinx.coroutines.CoroutineStart 5 | import kotlinx.coroutines.async 6 | import kotlinx.coroutines.delay 7 | import kotlinx.coroutines.runBlocking 8 | import kotlin.system.measureTimeMillis 9 | 10 | fun main() = runBlocking { 11 | val time = measureTimeMillis { 12 | val one = async(start = CoroutineStart.LAZY) { fun1() } 13 | val two = async(start = CoroutineStart.LAZY) { fun2() } 14 | // some computation 15 | one.start() // start the first one 16 | two.start() // start the second one 17 | println("The answer is ${one.await() + two.await()}") 18 | } 19 | println("Completed in $time ms") 20 | } 21 | 22 | suspend fun fun1(): Int { 23 | delay(1000L) // pretend we are doing something useful here 24 | return 13 25 | } 26 | 27 | suspend fun fun2(): Int { 28 | delay(1000L) // pretend we are doing something useful here, too 29 | return 29 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/retrofitexample/ReqResAPI.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.retrofitexample 2 | 3 | import retrofit2.Response 4 | import retrofit2.http.GET 5 | import retrofit2.http.Query 6 | 7 | interface ReqResAPI { 8 | 9 | @GET("users") 10 | suspend fun getUsers( 11 | @Query("page") page: Int = 1 12 | ): Response 13 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/retrofitexample/UsersResponse.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.retrofitexample 2 | 3 | 4 | import androidx.annotation.Keep 5 | import com.google.gson.annotations.SerializedName 6 | 7 | @Keep 8 | data class UsersResponse( 9 | @SerializedName("data") val users: List, 10 | @SerializedName("page") val page: Int, 11 | @SerializedName("per_page") val perPage: Int, 12 | @SerializedName("total") val total: Int, 13 | @SerializedName("total_pages") val totalPages: Int 14 | ) { 15 | @Keep 16 | data class User( 17 | @SerializedName("avatar") val avatar: String, 18 | @SerializedName("email") val email: String, 19 | @SerializedName("first_name") val firstName: String, 20 | @SerializedName("id") val id: Int, 21 | @SerializedName("last_name") val lastName: String 22 | ) 23 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/util/ActivityDataBinding.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ActivityDataBinding") 2 | 3 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.util 4 | 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.databinding.DataBindingUtil 8 | import androidx.databinding.ViewDataBinding 9 | import androidx.fragment.app.FragmentActivity 10 | 11 | fun FragmentActivity.dataBinding(): Lazy = object : Lazy { 12 | private var binding: T? = null 13 | override fun isInitialized(): Boolean = binding != null 14 | override val value: T 15 | get() = binding ?: bind(getContentView()).also { 16 | it.lifecycleOwner = this@dataBinding 17 | binding = it 18 | } 19 | 20 | private fun FragmentActivity.getContentView(): View { 21 | return checkNotNull(findViewById(android.R.id.content).getChildAt(0)) { 22 | "Call setContentView or Use Activity's secondary constructor passing layout res id." 23 | } 24 | } 25 | 26 | private fun bind(view: View): T = DataBindingUtil.bind(view)!! 27 | } 28 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/util/BindingAdapters.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.util 2 | 3 | import android.view.View 4 | import android.widget.TextView 5 | import androidx.databinding.BindingAdapter 6 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.model.ViewState 7 | 8 | /** 9 | * Display or hide a view based on a condition 10 | */ 11 | @BindingAdapter("visibilityBasedOn") 12 | fun View.visibleWhen(condition: Boolean) { 13 | visibility = if (condition) View.VISIBLE else View.GONE 14 | 15 | } 16 | 17 | 18 | /** 19 | * Set text of [TextView] depending on success or error from network or database 20 | */ 21 | @BindingAdapter("postState") 22 | fun TextView.postState(viewState: ViewState?) { 23 | viewState?.let { 24 | text = if (viewState.shouldShowErrorMessage()) { 25 | viewState.getErrorMessage() 26 | } else { 27 | viewState.data 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/util/FragmentDataBinding.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("FragmentDataBinding") 2 | 3 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.util 4 | 5 | import android.view.View 6 | import androidx.databinding.DataBindingUtil 7 | import androidx.databinding.ViewDataBinding 8 | import androidx.fragment.app.Fragment 9 | import kotlin.properties.ReadOnlyProperty 10 | import kotlin.reflect.KProperty 11 | 12 | fun Fragment.dataBinding(): ReadOnlyProperty { 13 | return object : ReadOnlyProperty { 14 | @Suppress("UNCHECKED_CAST") 15 | override fun getValue(thisRef: Fragment, property: KProperty<*>): T { 16 | (requireView().getTag(property.name.hashCode()) as? T)?.let { return it } 17 | return bind(requireView()).also { 18 | it.lifecycleOwner = thisRef.viewLifecycleOwner 19 | it.root.setTag(property.name.hashCode(), it) 20 | } 21 | } 22 | 23 | private fun bind(view: View): T = DataBindingUtil.bind(view)!! 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/util/LifecycleOwnerExtension.kt: -------------------------------------------------------------------------------- 1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.util 2 | 3 | import androidx.lifecycle.LifecycleOwner 4 | import androidx.lifecycle.LiveData 5 | import androidx.lifecycle.Observer 6 | 7 | fun LifecycleOwner.observe(liveData: LiveData, predicate: (T) -> Unit) { 8 | liveData.observe(this, Observer { it?.let { predicate(it) } }) 9 | } -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 15 | 16 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/res/layout/activity_retrofit.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | -------------------------------------------------------------------------------- /Tutorial1-1CoroutinesBasics/src/main/res/layout/fragment2_basics.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 |