코루틴이 무엇인지에 대한 정의는 인터넷에 넘쳐나기 때문에, 다시 추가적으로 설명하지 않으려고 한다. 다만 최근 구글에서 안드로이드 플랫폼에서 Concurrent job을 처리하기 위한 공식적인 방법으로 권장하기 시작했다는 점을 언급하고 싶다. 만약 코틀린으로만 된 프로젝트라면 RxJava나 다른 솔루션보다는 코틀린에서 제공하고 구글이 공식적으로 인정한 코루틴을 사용하는 것이 자연스러운 선택이라고 할 수 있을 것 같다. 그럼, 코틀린은 어떤 모습이고, 왜 cocurrent job을 처리하는데 좋다고 할까? 먼저, 자바의 Thread에 대해 간략히 살펴보기로 하자. Thread 의 제약점을 통해 왜 코루틴이 유용한지 이해하는데 도움이 될 것이다. fun main() { new Thread() { printl..
요즘 Coroutines는 좀 더 심도있게 공부하기 위해 온라인 강좌를 듣고 있는 중이다. 강좌가 진행되면 될수록 드는 생각이지만 Kotlin Coroutines는 생각만큼 단순하지 않다는 것이다. 아니 상당히 까다로운 프레임웤이라는 것이다. 주된 이유는 내부 메카니즘의 복잡함에 있다고 할 수 있는데, 특히 Cancellation과 Exception Handling으로 들어가면 직관적이지 않은 동작 때문에 Coroutines가 어떻게 동작하는지 정확한 이해가 없을 경우 정말로 골치아픈 버그를 접하게 될 가능성이 많다는 점이다. 예를 하나만 들어보자. class CoroutineTest { @Test fun exceptionTest() { runBlocking { val scopeJob = Job() va..
오늘 아침, 코틀린 커뮤니티 포럼에 계산값에 대한 질문이 올라와 있었다. Double 연산이 제대로 되지 않는다는 것이었다. Original discussions: discuss.kotlinlang.org/t/how-to-do-an-operation-on-a-variable-and-assign-it-that-new-value-for-easing-calculations/19621 [ How to do an operation on a variable and assign it that new value for easing calculations? Do calculations with double seems a mess. But within my calculation i have numbers like 2.24..
실제 업무를 하다보면, Build flavour와 Build type에 따라 각각 다른 endpoint에 접속할 경우가 많다. 예를 들면, 개발시에는 개발서버나 테스트 서버에 있는 API를 사용을 하고 릴리스 후에는 프로덕션에 있는 API를 사용할 필요가 생긴다. 또는 개발시에는 Base URL을 세팅에서 바꿀 수 있는 옵션을 제공할 때도 있다. 어떻게 하면 좀 더 깔끔하게 빌드환경에 따른 Base URl 관리를 할 수 있을까? 여러가지 다양한 구현 방법이 존재하겠지만, Bridge Pattern이 이런 경우에 적합할 것 같아 보인다. dev와 prod flavour가 있고, Dev, UAT, PROD 환경이 있다고 하자. 그렇다면 다음과 같은 형태로 클래스를 설계해 볼 수 있을 것이다. Flavour는..
brew tap AdoptOpenJDK/openjdk brew cask install adoptopenjdk8If brew exists error occurs, run rm /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask-versions/Casks/adoptopenjdk8.rb) Java version check > java -versionJava location > which java /usr/bin/java
Navigation Component를 사용하면서 접하게 되는 Usecase는 Splash Screen이다. 왜냐하면 Splash Screen은 앱이 실행될 때 제일 먼저 떴다가 사라져야 하고, 백스택에서 제거되어야 하기 때문이다. 네비게이션 그래프를 보자. 아래와 같이 두개의 SplashFragment와 MainFragment가 존재하고 SplashFragment가 시작 Fragment이다. 아래는 SplashFragment 클래스이다. 3초 후에 MainFragment로 이동한다. class SplashFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstance..
startActivityForResult를 사용할 때, 아래처럼 바로 결과를 받아오면 코드가 더 간결하고 읽기 쉬워질 거라는 생각을 여러번 했었다. val intent = Intent(this, AnotherActivity::class.java) val activityResult = startActivityForResult(intent) if (activityResult.resultCode = Activity.RESULT_OK) { //doSomething() } Coroutines에서 지원하는 CompletableDeffered란 녀석을 이용하면 위와 같은 순차적인 코드가 가능해 진다. Activty에 다음 코드를 추가한다. class DefferedActivity: AppCompatActivity()..
From the previous blog, how can we dismiss loadin spinner after data has been loaded. SectionLifecycle.dispatchLoadingEvent We can send loading event to GroupSection to stop loading. We can simple add one line of code to onDataLoaded(). HeroesComponent.dispatchLoadingEvent(c, false, LoadingEvent.LoadingState.SUCCEEDED, null) Your onDataLoaded() will look like following now. @OnEvent(HeroModel::c..