├── .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 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/layout/rowlayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial1-1CoroutinesBasics/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
7 | #FF8A65
8 | #008898
9 | #5E35B1
10 | #388E3C
11 |
12 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Tutorial1-1Basics
3 | Select fragment
4 |
5 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/test/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/chapter6_network/test_suite/PostNetworkJUnit4TestSuite.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.test_suite
2 |
3 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.PostsCoroutineViewModelTest
4 | import com.smarttoolfactory.tutorial1_1coroutinesbasics.chapter6_network.PostsRepositoryTest
5 | import org.junit.runner.RunWith
6 | import org.junit.runners.Suite
7 |
8 |
9 | // Runs all unit tests with JUnit4.
10 | @RunWith(Suite::class)
11 | @Suite.SuiteClasses(
12 | PostsRepositoryTest::class,
13 | PostsCoroutineViewModelTest::class
14 | )
15 | class PostNetworkJUnit4TestSuite
16 |
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/test/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/util/rules/MockWebServerRule.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.util.rules
2 |
3 | import okhttp3.mockwebserver.MockWebServer
4 | import org.junit.rules.TestRule
5 | import org.junit.runner.Description
6 | import org.junit.runners.model.Statement
7 |
8 | /**
9 | * Test rule for JUnit4 to invoke actions which are
10 | * start [MockWebServer],
11 | * run the test ,
12 | * and shut [MockWebServer] down after the test is run.
13 | */
14 | class MockWebServerRule : TestRule {
15 |
16 | val mockWebServer = MockWebServer()
17 |
18 | override fun apply(
19 | base: Statement,
20 | description: Description
21 | ): Statement {
22 |
23 | return object : Statement() {
24 |
25 | @Throws(Throwable::class)
26 | override fun evaluate() {
27 | mockWebServer.start()
28 | base.evaluate()
29 | mockWebServer.shutdown()
30 | }
31 |
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Tutorial1-1CoroutinesBasics/src/test/java/com/smarttoolfactory/tutorial1_1coroutinesbasics/util/rules/TestCoroutineRule.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial1_1coroutinesbasics.util.rules
2 |
3 | import kotlinx.coroutines.Dispatchers
4 | import kotlinx.coroutines.ExperimentalCoroutinesApi
5 | import kotlinx.coroutines.test.*
6 | import org.junit.rules.TestRule
7 | import org.junit.runner.Description
8 | import org.junit.runners.model.Statement
9 |
10 | @ExperimentalCoroutinesApi
11 | class TestCoroutineRule : TestRule {
12 |
13 | val testCoroutineDispatcher = TestCoroutineDispatcher()
14 |
15 | val testCoroutineScope = TestCoroutineScope(testCoroutineDispatcher)
16 |
17 | override fun apply(base: Statement, description: Description?) = object : Statement() {
18 |
19 | @Throws(Throwable::class)
20 | override fun evaluate() {
21 |
22 | Dispatchers.setMain(testCoroutineDispatcher)
23 |
24 | base.evaluate()
25 |
26 | Dispatchers.resetMain()
27 | try {
28 | testCoroutineScope.cleanupTestCoroutines()
29 | } catch (exception: Exception) {
30 | exception.printStackTrace()
31 | }
32 | }
33 | }
34 |
35 | fun runBlockingTest(block: suspend TestCoroutineScope.() -> Unit) =
36 | testCoroutineScope.runBlockingTest { block() }
37 |
38 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/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
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/adapter/ChapterSelectionAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.adapter
2 |
3 |
4 | import com.smarttoolfactory.tutorial2_1flowbasics.R
5 | import com.smarttoolfactory.tutorial2_1flowbasics.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 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter2_network/PostRemoteRepository.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter2_network
2 |
3 | import com.smarttoolfactory.tutorial2_1flowbasics.data.api.PostApi
4 | import com.smarttoolfactory.tutorial2_1flowbasics.data.model.PostDTO
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.flow.Flow
7 | import kotlinx.coroutines.flow.flow
8 | import kotlinx.coroutines.flow.flowOn
9 |
10 | class PostRemoteRepository(private val postApi: PostApi) {
11 |
12 | fun getPostFlow(): Flow> {
13 | return flow {
14 | // Runs in DefaultDispatcher-worker-2, or the thread flowOn runs which is below this function in UseCase class
15 | println("😱 PostRemoteRepository getPostFlow() thread: ${Thread.currentThread().name}")
16 | emit(postApi.getPosts())
17 | }
18 | .flowOn(Dispatchers.IO)
19 | }
20 |
21 | suspend fun getPosts() = postApi.getPosts()
22 | }
23 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter3_database/PostDBRepository.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter3_database
2 |
3 | import com.smarttoolfactory.tutorial2_1flowbasics.data.db.PostDao
4 | import com.smarttoolfactory.tutorial2_1flowbasics.data.model.PostEntity
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.flow.Flow
7 | import kotlinx.coroutines.flow.flowOn
8 | import kotlinx.coroutines.flow.map
9 |
10 | class PostDBRepository(private val postDao: PostDao) {
11 |
12 | fun getPostListFlow(): Flow> {
13 | println("🤔 PostDBRepository getPostFlow() thread: ${Thread.currentThread().name}")
14 | return postDao.getPostListFlow().map {
15 | println("🤔 PostDBRepository getPostFlow() MAP thread: ${Thread.currentThread().name}")
16 | it
17 | }
18 | }
19 |
20 | fun getPostByIdFlow(id:Int) =postDao.getPostFlow(id)
21 |
22 | suspend fun getPostList() = postDao.getPostList()
23 |
24 | suspend fun getPostById(id: Int) = postDao.getPost(id)
25 |
26 | suspend fun getPostCount() = postDao.getPostCount()
27 |
28 | suspend fun savePosts(posts: List) = postDao.insert(posts)
29 | }
30 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter3_database/mock/MockProductFactory.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter3_database.mock
2 |
3 | import android.app.Application
4 | import android.content.res.AssetManager
5 | import com.google.gson.GsonBuilder
6 | import com.smarttoolfactory.tutorial2_1flowbasics.data.db.PostDao
7 | import com.smarttoolfactory.tutorial2_1flowbasics.data.model.Post
8 |
9 |
10 | class MockProductFactory constructor(
11 | private val postDao: PostDao,
12 | private val application: Application
13 | ) {
14 |
15 |
16 | fun generateMockList(): List {
17 | val response = application.assets.readAssetsFile("mock/response.json")
18 | return GsonBuilder().create().fromJson(response, Array::class.java).asList()
19 | }
20 |
21 |
22 | companion object {
23 | const val KEY_FIRST_START = "FIRST_START"
24 | }
25 |
26 |
27 | private fun AssetManager.readAssetsFile(fileName: String): String =
28 | open(fileName).bufferedReader().use { it.readText() }
29 |
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter4_single_source_of_truth/Activity4SingleSourceOfTruth.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter4_single_source_of_truth
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import androidx.fragment.app.FragmentContainerView
6 | import androidx.navigation.Navigation
7 | import androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
8 | import androidx.navigation.findNavController
9 | import androidx.navigation.fragment.NavHostFragment
10 | import androidx.navigation.fragment.findNavController
11 | import com.smarttoolfactory.tutorial2_1flowbasics.R
12 |
13 | class Activity4SingleSourceOfTruth : AppCompatActivity() {
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.activity4_single_source_of_truth)
18 |
19 | title = "Single Source of Truth Coroutines Flow"
20 |
21 | val navHostFragment: NavHostFragment = supportFragmentManager
22 | .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
23 |
24 | navHostFragment.findNavController().setGraph(R.navigation.nav_graph_post_list)
25 | }
26 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter4_single_source_of_truth/DispatcherProvider.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter4_single_source_of_truth
2 |
3 | import kotlinx.coroutines.CoroutineDispatcher
4 |
5 | data class DispatcherProvider(
6 | val ioDispatcher: CoroutineDispatcher,
7 | val defaultDispatcher: CoroutineDispatcher
8 | )
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter4_single_source_of_truth/post_list/AbstractPostViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter4_single_source_of_truth.post_list
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import com.smarttoolfactory.tutorial2_1flowbasics.data.model.Post
7 | import com.smarttoolfactory.tutorial2_1flowbasics.data.model.ViewState
8 | import com.smarttoolfactory.tutorial2_1flowbasics.util.Event
9 |
10 | abstract class AbstractPostViewModel : ViewModel() {
11 |
12 | internal val _goToDetailScreen = MutableLiveData>()
13 | val goToDetailScreen: LiveData>
14 | get() = _goToDetailScreen
15 |
16 | internal val _postViewState = MutableLiveData>>()
17 | val postViewState: LiveData>>
18 | get() = _postViewState
19 |
20 | abstract fun getPosts()
21 |
22 | abstract fun refreshPosts()
23 |
24 | abstract fun onClick(post: Post)
25 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/data/model/Post.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.data.model
2 |
3 | import android.os.Parcelable
4 | import kotlinx.android.parcel.Parcelize
5 |
6 | @Parcelize
7 | data class Post(
8 | val id: Int,
9 | val userId: Int,
10 | val title: String,
11 | val body: String
12 | ) : Parcelable
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/data/model/PostDTO.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.data.model
2 |
3 |
4 | data class PostDTO(
5 | val id: Int,
6 | val userId: Int,
7 | val title: String,
8 | val body: String
9 | )
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/data/model/PostEntity.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.data.model
2 |
3 | import androidx.room.Entity
4 | import androidx.room.PrimaryKey
5 |
6 | @Entity(tableName = "post")
7 | data class PostEntity(
8 | @PrimaryKey
9 | val id: Int,
10 | val userId: Int,
11 | val title: String,
12 | val body: String
13 | )
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/data/model/ViewState.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.data.model
2 |
3 | import kotlinx.coroutines.CoroutineDispatcher
4 | import kotlinx.coroutines.flow.*
5 |
6 |
7 | class ViewState(
8 | val status: Status,
9 | val data: T? = null,
10 | val error: Throwable? = null
11 | ) {
12 |
13 | fun isSuccess() = status == Status.SUCCESS
14 |
15 | fun isLoading() = status == Status.LOADING
16 |
17 | fun getErrorMessage() = error?.message
18 |
19 | fun shouldShowErrorMessage() = error != null && status == Status.ERROR
20 | }
21 |
22 | enum class Status {
23 | LOADING,
24 | SUCCESS,
25 | ERROR
26 | }
27 |
28 | fun Flow.convertToFlowViewState(dispatcher: CoroutineDispatcher): Flow> {
29 |
30 | return this
31 | .map { postList -> ViewState(status = Status.SUCCESS, data = postList) }
32 | .catch { cause: Throwable -> emitAll(flowOf(ViewState(Status.ERROR, error = cause))) }
33 | .flowOn(dispatcher)
34 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/model/ActivityClassModel.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.model
2 |
3 | data class ActivityClassModel(val clazz: Class<*>, val description: String = clazz.name)
4 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/java/com/smarttoolfactory/tutorial2_1flowbasics/util/EmptyDataException.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.util
2 |
3 | class EmptyDataException(message:String):Exception(message)
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_1_raster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_1_raster.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_2_raster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_2_raster.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_3_raster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_3_raster.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_4_raster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_4_raster.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_5_raster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_5_raster.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_6_raster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/drawable/avatar_6_raster.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/layout/activity4_single_source_of_truth.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
18 |
19 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
15 |
16 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/layout/rowlayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/Tutorial2-1FlowBasics/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/navigation/nav_graph_post_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
20 |
21 |
22 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/navigation/nav_graph_post_list_rxjava3.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Tutorial2-1FlowBasics
3 | Post Detail
4 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/test-shared/java/com/smarttoolfactory/tutorial2_1flowbasics/TestCoroutineRule.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics
2 |
3 | import kotlinx.coroutines.Dispatchers
4 | import kotlinx.coroutines.ExperimentalCoroutinesApi
5 | import kotlinx.coroutines.test.*
6 | import org.junit.rules.TestRule
7 | import org.junit.runner.Description
8 | import org.junit.runners.model.Statement
9 |
10 | @ExperimentalCoroutinesApi
11 | class TestCoroutineRule : TestRule {
12 |
13 | val testCoroutineDispatcher = TestCoroutineDispatcher()
14 |
15 | val testCoroutineScope = TestCoroutineScope(testCoroutineDispatcher)
16 |
17 | override fun apply(base: Statement, description: Description?) = object : Statement() {
18 |
19 | @Throws(Throwable::class)
20 | override fun evaluate() {
21 |
22 | Dispatchers.setMain(testCoroutineDispatcher)
23 |
24 | base.evaluate()
25 |
26 | Dispatchers.resetMain()
27 | try {
28 | testCoroutineScope.cleanupTestCoroutines()
29 | } catch (exception: Exception) {
30 | exception.printStackTrace()
31 | }
32 | }
33 | }
34 |
35 | fun runBlockingTest(block: suspend TestCoroutineScope.() -> Unit) =
36 | testCoroutineScope.runBlockingTest { block() }
37 |
38 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/test/java/com/smarttoolfactory/tutorial2_1flowbasics/base/BaseCoroutineJUnit5Test.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.base
2 |
3 | import kotlinx.coroutines.Dispatchers
4 | import kotlinx.coroutines.test.TestCoroutineDispatcher
5 | import kotlinx.coroutines.test.TestCoroutineScope
6 | import kotlinx.coroutines.test.resetMain
7 | import kotlinx.coroutines.test.setMain
8 | import org.junit.jupiter.api.AfterEach
9 | import org.junit.jupiter.api.BeforeEach
10 | import org.junit.jupiter.api.TestInstance
11 |
12 |
13 | @TestInstance(TestInstance.Lifecycle.PER_CLASS)
14 |
15 | open class BaseCoroutineJUnit5Test {
16 |
17 | val testCoroutineDispatcher = TestCoroutineDispatcher()
18 | val testCoroutineScope = TestCoroutineScope(testCoroutineDispatcher)
19 |
20 |
21 | @BeforeEach
22 | open fun setUp() {
23 | // provide the scope explicitly, in this example using a constructor parameter
24 | Dispatchers.setMain(testCoroutineDispatcher)
25 | }
26 |
27 | @AfterEach
28 | open fun tearDown() {
29 | Dispatchers.resetMain()
30 | try {
31 | testCoroutineDispatcher.cleanupTestCoroutines()
32 | } catch (e: Exception) {
33 | e.printStackTrace()
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/test/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter1_operators/OperatorTest.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter1_operators
2 |
3 | import kotlinx.coroutines.channels.Channel
4 | import kotlinx.coroutines.flow.collect
5 | import kotlinx.coroutines.flow.consumeAsFlow
6 | import kotlinx.coroutines.launch
7 | import kotlinx.coroutines.test.runBlockingTest
8 | import org.junit.jupiter.api.Assertions.assertEquals
9 | import org.junit.jupiter.api.Test
10 |
11 | class OperatorTest {
12 |
13 |
14 | @Test
15 | fun test() = runBlockingTest {
16 |
17 | val subject = Channel()
18 | val values = mutableListOf()
19 |
20 | val job = launch {
21 | subject.consumeAsFlow()
22 | .collect {
23 | values.add(it)
24 | }
25 | }
26 | assertEquals(emptyList(), values)
27 | subject.send(1)
28 |
29 | assertEquals(listOf(1), values)
30 | job.cancel()
31 | }
32 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/test/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter4_single_source_of_truth/data/repository/PostRepoRxJava3ImplTest.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter4_single_source_of_truth.data.repository
2 |
3 | class PostRepoRxJava3ImplTest {
4 |
5 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/test/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter4_single_source_of_truth/data/repository/PostRepositoryImplTest.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter4_single_source_of_truth.data.repository
2 |
3 | class PostRepositoryImplTest {
4 |
5 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/test/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter4_single_source_of_truth/domain/GetPostsUseCaseFlowTest.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter4_single_source_of_truth.domain
2 |
3 | class GetPostsUseCaseFlowTest {
4 |
5 | }
--------------------------------------------------------------------------------
/Tutorial2-1FlowBasics/src/test/java/com/smarttoolfactory/tutorial2_1flowbasics/chapter4_single_source_of_truth/domain/GetPostsUseCaseRxJava3Test.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.tutorial2_1flowbasics.chapter4_single_source_of_truth.domain
2 |
3 |
4 | class GetPostsUseCaseRxJava3Test {
5 |
6 | }
--------------------------------------------------------------------------------
/features/post_detail/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/features/post_detail/src/androidTest/java/com/smarttoolfactory/post_detail/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.post_detail
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.smarttoolfactory.post_detail", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/features/post_detail/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/features/post_detail/src/main/java/com/smarttoolfactory/post_detail/PostDetailFragment.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.post_detail
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.databinding.DataBindingUtil
8 | import androidx.fragment.app.Fragment
9 | import com.smarttoolfactory.post_detail.databinding.FragmentPostDetailBinding
10 | import com.smarttoolfactory.tutorial2_1flowbasics.data.model.Post
11 |
12 |
13 | class PostDetailFragment : Fragment() {
14 |
15 |
16 | private lateinit var dataBinding: FragmentPostDetailBinding
17 |
18 | override fun onCreateView(
19 | inflater: LayoutInflater,
20 | container: ViewGroup?,
21 | savedInstanceState: Bundle?
22 | ): View? {
23 | dataBinding =
24 | DataBindingUtil.inflate(inflater, R.layout.fragment_post_detail, container, false)
25 | return dataBinding.root
26 | }
27 |
28 |
29 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
30 | super.onViewCreated(view, savedInstanceState)
31 |
32 | // Get RepoListItem from navigation component arguments
33 | val post = arguments?.get("post") as? Post?
34 |
35 | dataBinding?.item = post
36 | }
37 | }
--------------------------------------------------------------------------------
/features/post_detail/src/main/res/navigation/nav_graph_post_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/features/post_detail/src/test/java/com/smarttoolfactory/post_detail/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.smarttoolfactory.post_detail
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 | # Allow data binding to be incremental
23 | android.databinding.incremental=true
24 | # Disabling lint check. Descreases build time.
25 | gradle=build -x lint
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartToolFactory/CoroutinesAndFlowTutorials/fe901e663ea93207bf0f6ffe13b72717cb9653ef/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Aug 05 12:24:57 EET 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
7 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':features:post_detail'
2 | include ':Tutorial2-1FlowBasics'
3 | include ':External-Tutorial-Coroutines-CodeLab-Room-Retrofit-WorkManager'
4 | rootProject.name='Coroutines And Flow Tutorials'
5 | include ':Tutorial1-1CoroutinesBasics'
6 |
--------------------------------------------------------------------------------