코틀린

Language/Kotlin

NonCancellable Coroutines 사용해보기

이전 글에서 코루틴을 취소하는 방법에 대해 설명해보았다. 여기서 생각해볼만한 것이 하나 있는데 바로 CancellationException을 사용해코루틴을 종료시키기 직전 특정 작업을 하는 경우이다. 더 정확히 따지면 suspend function 호출이 필요하지만 불가능한 경우이다. 예제 코드와 같이 보자. 예제 코드fun main() = runBlocking { val job = launch(Dispatcher.Default) { repeat(10) { index -> if (isActive) { println("repeat $index") Thread.sleep(100) } else { ..

Language/Kotlin

Coroutines Cooperative Cancellation

이번 글에서는 코루틴을 취소할 때 어떤 취소 방법을 취해야하는지에 대해 설명해본다. 코루틴 안에서 반복문을 실행하는 도중 취소하는 상황을 예시로 보자. 코드 예제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까지만 실행됐을거라고 생각했다면 오산이다. 취소..

Language/Kotlin

LifecycleScope 간단히 알아보기

이번 글에서는 LifecycleScope를 소개해본다. 다만 제목 그대로 간단히 알아보려 하는데 이전 글에서 알아본 ViewModelScope와 비슷하기 때문이다. LifecycleScope의 lifecycle 알아보기생명주기는 생각보다 심플하다.  Lifecycle owner가 살아있는 동안 해당 스코프도 살아있게 된다. 상황에 따라 Activity, Fragment 등이 될 수 있다. 해당 owner가 destroy될 때 LifecycleScope에서 실행된 모든 코루틴은 cancel된다. 가장 대표적인 destroy 상황은 화면 회전에 의한 Activity destroy이다. 이렇게 되면 특정 작업을 수행하다가도 cancel되어버리는 상황이 발생하기에이런 경우, ViewModelScope를 사용하는..

Language/Kotlin

ViewModelScope 알아보기

이번에는 드디어 이전 예제들에서 사용해왔던 viewModelScope에 대해 알아보도록 하자. ViewModelScope LifecycleviewModelScope는 ViewModel의 lifecycle과 연관되어 있다. 다르게 말하면 viewModelScope에서 시작된 코루틴은 ViewModel이 살아있는 경우 계속 실행된다. 당연히 ViewModel onCleared 메소드가 호출되는 시점에viewModelScope에서 시작된 코루틴은 모두 cancel된다. ViewModelScope 구현 살펴보기이 스코프는 ViewModel이 clear될 때 자동으로 cancel된다는위의 lifecycle 설명에서 말했던 부분이 보인다. Dispatcher 확인하기MainCoroutineDispatcher.imm..

Language/Kotlin

GlobalScope 알아보기

GlobalScope에 대해 설명하기 전 가장 저명한 사실을 하나 얘기하고 시작한다. 우리는 앱에서 GlobalScope를 사용할 일이 거의 없을 것이다. 공식문서에서도 되도록 사용하지 않는 것을 권장하는 뉘앙스를 풍긴다. 사용하지 않을 이유 찾기 제한된 수명 주기가 없다.이 뜻을 앱 관점에서 보면 GlobalScope 안에서 시작된 코루틴은앱 프로세스가 종료될 때까지 종료되지 않는다는 것이다. 어떠한 Job에도 엮이지 않는다.제목 그대로를 코드로 확인해보자.println("GlobalScope Job: ${GlobalScope.coroutineContext[Job]}")이 코드를 실행시켜보자.GlobalScope Job: null위와 같은 결과가 나온다. 위 결과로 유추할 수 있는 것이 또 하나가 생겼..

Android

Android add library using toml

toml 파일을 사용하게 된 계기이번 신규 프로젝트를 진행하게 되었는데,그에 따라 프로젝트 자체를 새로 생성하면서 build.gradle 언어를 Kotlin DSL로 설정했더니Android Studio Koala를 쓰는 나에게 toml이 포함된 프로젝트가 생성되었다. 여기저기 오픈소스 라이브러리에서 혹은 developer 사이트에서도 자주 볼 수 있는 녀석이라이번 기회에 써보기로 했다. Retrofit 추가해보기어차피 대부분 앱은 네트워크 작업이 필요하고 그에 따라 가장 대중적인 라이브러리는 단연 Retrofit일 것이다. 하지만, 기존 toml을 사용해본적 없는 나로서는 상당히 검색할 시간이 필요했다. 먼저 toml 파일 수정하기[versions]... //retrofit = "2.11.0"serial..

Android

Android QR Code Generation

기능 추가 배경QR코드를 통해 로그인 정보를 공유한다. 물론 로그인 정보는 민감한 정보이므로 암호화가 필요하다. 장점서버가 필요없다.OS간 직접 파일을 옮기는 것이 아니기에 플랫폼 제약이 없다. 단점길이에 제한이 있다.카메라만으로도 정보가 보일 수 있어 비교적 보안에 약한 편이다.(암호화를 한다고 해도 말이다.) 라이브러리 추가하기여기서 사용한 라이브러리는 이전 글에서도 등장한 적이 있다.https://github.com/journeyapps/zxing-android-embedded GitHub - journeyapps/zxing-android-embedded: Barcode scanner library for Android, based on the ZXing decoderBarcode scanner l..

Language/Kotlin

Coroutines 여러 개로 연산 속도 높이기

이번 글에서는 전에 다루었던 withContext로 스레드를 전환 후 연산 작업을 더 빠르게 수행해보려고 한다. 기존에는 팩토리얼 계산을 Default Dispatcher를 사용해 하나의 코루틴에서 연산을 수행했다.이번에는 여러 개의 코루틴에서 연산을 수행한다. 어떤 구조로 실행할까팩토리얼을 몇개의 코루틴으로 나눠 실행할지 정해야 한다.실행할 코루틴 갯수만큼 연산할 숫자의 길이를 동등하게 분배한다.작은 범위를 계산하는 서브 코루틴을 동시에 실행시킨다.모든 서브 코루틴이 종료되는 것을 기다린다.모든 서브 코루틴이 종료되면 fold 함수를 사용해 작은 범위들을 모두 곱한다. 코드suspend fun calculateFactorial( factorialOf: Int, numberOfC..

Android

Android Compose WebView PullToRefresh 기능 구현하기

제목에서 본 기능은 갤럭시 유저라면 삼성 브라우저를 통해 익숙한 기능일 것이다. 다만, 이 기능을 앱의 웹뷰에서 적용해야하는지는 기획에 따라 달라지겠지만나는 이번에 Compose 공부도 하는 겸 추가해보았다. 본격적으로 글을 시작하기 전 내가 Compose에 대한 이해가 상당히 미진하다는 점을 알린다. Material3 라이브러리 버전먼저 나는 이번 프로젝트에서 compose material3 라이브러리 최신 버전인 1.3.1을 사용했다. pullToRefresh가 1.3.0 버전에서 추가되었기 때문이다. 제목에 굳이 웹뷰를 적은 이유보통 android compose pulltorefresh를 검색어로 입력하면LazyColumn에 있는 리스트를 갱신하는 예제가 매우 많다. 하지만, 나는 전체화면인 웹뷰 ..

Language/Kotlin

Java, Kotlin Interoperability 해결하기

이번 글은 최근 Java -> Kotlin 변환과Java 클래스에서 Kotlin 클래스를 사용하면서 겪은 이슈를 공유해본다. 문제 상황 설명먼저 Java 클래스를 Kotlin 클래스로 변경했다. 이 때 특정 변수는 자료형을 변경하면서까지 리팩토링을 진행했다. 그리고 다시 변경한 Kotlin 클래스를 Java 클래스에서 사용하는 부분이 필요했다.(아래처럼 말이다)class SomeData { var a: UInt = 0 var b: Int = 0}public class User { public void someMethod() { SomeData someData = new SomeData(); someData.getB(); someData.getA(); }} Kot..