Exception Handling Using ExceptionHandler in Coroutines
·
Study/Kotlin
이번에는 CoroutineExceptionHandler로 예외 처리를 해보도록 하자. 기존 try-catch 구문과는 어떤 차이가 있는지도 볼 예정이다. 처리할 코드val scope = CoroutineScope(Job())scope.launch { throw RuntimeException()}Thread.sleep(1000) CoroutineExceptionHandler 사용 지점이 핸들러는 Coroutine의 Context 요소이다. 이전 글에서의 기억을 떠올려본다면 가장 대표적인 Context 요소는 Dispatcher일 것이다. 또한, '+' 연산자를 사용하면 여러 Context 요소를 사용할 수 있다. 그럼 위 코드에서 어떤 위치에 핸들러를 주입해야할까? 정답은 두 위치에서 가능한데, 하나는 J..
Exception Handling Using try-catch Clause in Coroutines
·
Study/Kotlin
이번 글은 코루틴에서 try-catch절을 사용해 예외 처리를 해보는 시간이 될 것이다. 일반적인 예외 처리 상기하기fun main() { generateException()}fun generateException() { throw RuntimeException()}이런 예외를 try-catch절로 처리한 상황과 그렇지 않은 상황을 떠올려보자. 먼저 예외 처리를 해두었다면 프로그램이 정상적으로 실행이 종료된다. 그렇지 않은 경우 로그를 남기며 프로그램에 크래시가 발생한다. 코루틴에 적용해보기fun main() { val scope = CoroutineScope(Job()) scope.launch { generateException() } Thread.sleep(100)}fu..
럭스:시적해상도(Lux: Poetic Resolution) in DDP
·
주저리주저리/전시회
벌써 1년반이 다 되어가는 시점에 다녀온 전시회를 이제서야 돌아보고 있다. 뜬금없이 무슨 전시회?그냥 집에서 인스타 피드를 슥슥 내리다보니 신기한 영상이 있었다. 누군가 걸어가는데 모습이 계속 바뀌는 게 아닌가. 근데 그냥 그 모습을 보다보니 영상이 끝나버렸다. 멍하니 보다 영상이 끝나버리니 상당히 아쉬웠다. 알고보니 전시회 홍보 영상이었고, 그럼 비슷하게 디지털 멍하기 좋은 영상들이 더 많겠다는 생각이 들었다. 반차내고 평일에 가는 판단그래서 정말 충동적으로 인터파크에서 온라인 예매를 했다. 딱히 입장 날짜가 정해진 티켓은 아니었고 기간 내 언제든 입장가능한 티켓이었다. 언제 가볼까 생각하다 금요일 오후 반차를 내고 가면 어떨까 생각하게 되었다. 먼저 결과를 얘기하면 이 판단은 매우 좋았다. 일단 사람..
NonCancellable Coroutines 사용해보기
·
Study/Kotlin
이전 글에서 코루틴을 취소하는 방법에 대해 설명해보았다. 여기서 생각해볼만한 것이 하나 있는데 바로 CancellationException을 사용해코루틴을 종료시키기 직전 특정 작업을 하는 경우이다. 더 정확히 따지면 suspend function 호출이 필요하지만 불가능한 경우이다. 예제 코드와 같이 보자. 예제 코드fun main() = runBlocking { val job = launch(Dispatcher.Default) { repeat(10) { index -> if (isActive) { println("repeat $index") Thread.sleep(100) } else { ..
Coroutines Cooperative Cancellation
·
Study/Kotlin
이번 글에서는 코루틴을 취소할 때 어떤 취소 방법을 취해야하는지에 대해 설명해본다. 코루틴 안에서 반복문을 실행하는 도중 취소하는 상황을 예시로 보자. 코드 예제fun main() = runBlocking { val job = launch(Dispatcher.Default) { repeat(10) { index -> println("repeat $index") Thread.sleep(100) } } delay(250) println("Cancel coroutine") job.cancel()}위 예제를 실행한 결과를 먼저 예상해보자. 만약 이 코드가 정상적으로 repeat 0~2까지만 실행됐을거라고 생각했다면 오산이다. 취소..
Android Tester 환경 구축하기(from direct APK to Firebase App Distribution)
·
Dev experience/Android
이번 글에서는 테스터 환경을 어떻게 변화시켜왔는지 공유해보려 한다. 이 과정은 체감상 내 답답함 80%, 개척 20% 정도의 시간 소요가 있던 작업이다. 윗 문장을 이해하기 힘들 수 있다. 내 시간 흐름이 어땠는지 적어보겠다. APK 직접 배포하기회사에 처음 들어와서 어떤 업데이트 사항이 생기면 완성된 결과물을 QA팀에 전달해야 했다. 이 때, APK를 직접 빌드해서 메일로 전달했다. 초반에는 귀찮지 않았다. 그 이유로는드디어 내가 회사에서 일을 하는구나메일 용량 제한에 제약이 없다.그렇게 나는 점점 배포해야할 앱이 많아지고,결국 그룹웨어가 변경되고 나서는 메일함에 용량이라는 제약이 생기기 시작했다. 내가 QA팀에 APK를 전달할 때마다 메일함이 차오르기 시작했다.(+ 타 부서에서 설치파일을 원하는 경우..
Android Add Resource Value With Build Type And Flavor
·
Dev experience/Android
이번 글에서는 build type과 flavor에 따라 resValue를 추가하는 작업을 해볼 것이다. 이게 왜 필요했을까언제나 그렇듯 평범한 버그 수정, 신규 기능 추가를 반복하던 중다른 서버 주소 줄테니 이것도 따로 빌드해줘이런 요청을 받은 것이다. 물론 이런 요청이 단발적이라면 모를까내가 듣기로는 이후로 몇 번은 더 받을 요청이라는 생각이 들었다. 그래서 아예 flavor를 하나 추가해 debug, release 빌드 타입을 포함한 총 4개의 빌드를 구성했다. 방법 설명여기서 방법이 갈린다. 최신 프로젝트 생성 시엔 build.gradle.kts가 기본으로 설정되기에Groovy, Kotlin 모두 적용법을 찾아보았다. Groovy에서 적용하기android { ... buildTypes { ..
Android EditText Text Repeating(글자 복제되는 현상)
·
Dev experience/Android
오늘은 EditText에서 문자 입력 시 글자가 계속 복제되었던 문제를 소개한다. 발생 배경ID 입력을 모두 소문자로 강제해달라는 요구가 있었다. 이전에 모두 대문자로 강제해본 기억이 있었고, 그 때 사용했던 방법은 EditText.setFilters 였다.editText.filters = arrayOf(InputFilter.AllCaps())이런 식으로 말이다. 그래서 InputFilter를 잘 조절하면 소문자 강제도 어렵지 않겠다는 생각이 들었다. 그렇게 탄생한 코드는 아래와 같다.editText.filters = arrayOf(InputFilter { inputText, i, i2, spanned, i3, i4 -> inputText.toString().lowercase()}되게 합리적인 코드라고 ..
LifecycleScope 간단히 알아보기
·
Study/Kotlin
이번 글에서는 LifecycleScope를 소개해본다. 다만 제목 그대로 간단히 알아보려 하는데 이전 글에서 알아본 ViewModelScope와 비슷하기 때문이다. LifecycleScope의 lifecycle 알아보기생명주기는 생각보다 심플하다.  Lifecycle owner가 살아있는 동안 해당 스코프도 살아있게 된다. 상황에 따라 Activity, Fragment 등이 될 수 있다. 해당 owner가 destroy될 때 LifecycleScope에서 실행된 모든 코루틴은 cancel된다. 가장 대표적인 destroy 상황은 화면 회전에 의한 Activity destroy이다. 이렇게 되면 특정 작업을 수행하다가도 cancel되어버리는 상황이 발생하기에이런 경우, ViewModelScope를 사용하는..
ViewModelScope 알아보기
·
Study/Kotlin
이번에는 드디어 이전 예제들에서 사용해왔던 viewModelScope에 대해 알아보도록 하자. ViewModelScope LifecycleviewModelScope는 ViewModel의 lifecycle과 연관되어 있다. 다르게 말하면 viewModelScope에서 시작된 코루틴은 ViewModel이 살아있는 경우 계속 실행된다. 당연히 ViewModel onCleared 메소드가 호출되는 시점에viewModelScope에서 시작된 코루틴은 모두 cancel된다. ViewModelScope 구현 살펴보기이 스코프는 ViewModel이 clear될 때 자동으로 cancel된다는위의 lifecycle 설명에서 말했던 부분이 보인다. Dispatcher 확인하기MainCoroutineDispatcher.imm..