본문 바로가기
반응형

Android 개발238

Playstore 앱 제목 수정 요청 케이스 오랜만에 업데이트한 앱이 있었는데요.예전에는 무료 앱인 경우,유저들에게 어필하기 위해서 '무료'나 'Free'라는 단어를,제목에 넣었습니다. 그런데 오랜만에 앱을 업데이트해서 올렸더니,다음과 같이 수정하라고 메일이 날아왔습니다.    핵심은 며칠까지 수정해서 제출 안 하면,플레이스토어에서 앱을 삭제하겠다는 것입니다. 무거운 마음으로,Playstore에 접속해 보니,다행히 다음과 같이 가이드가 나와 있습니다.가격이나 프로모션을 나타내는 키워드를 사용하면 안 됩니다.이런 점은, 예전보다 구글이 많이 좋아진 것 같습니다.  바로 제목에 포함되어 있던 Free를 빼고,스토어 등록정보를 업데이트하였습니다. 날이 갈수록 구글스토어의 정책은 타이트해져 가고 있는데요.구글 플레이스토어에 앱 이름을 등록할 때,가.. 2024. 11. 8.
RxJava first()와 single()의 차이 총정리 RxJava에서 Observable을 Single타입으로 변환할 수 있는 방법이 있는데요.바로 first()와 single()을 사용하는 것 입니다.오늘은 이 둘의 차이를 알아보고 적절하게 사용하는 방법에 대해 보겠습니다. 1. first()와 single의 차이RxJava의 Observable의 first()나 single()을 사용하면,하나의 아이템만을 구독할 수 있습니다. 이 둘을 표로 비교하면 다음과 같습니다.  first()single()사용스트림의 첫 번째 항목만 필요할 때 사용정확히 하나의 항목만 방출되는지 확인하고, 그 항목을 방출(여러개 방출시 에러)에러처리비어있으면 NoSuchElementException발생 시킴비어있거나 둘 이상의 항목을 포함하면 에러를 발생 시킴완료 시점첫 번째 항.. 2024. 11. 4.
RxJava concatMap 정리: flatMap과 비교하며 이해하기 비동기 병렬 처리는 성능 향상에 큰 도움이 되지만, 데이터의 처리 순서가 중요한 상황도 많습니다.예를 들어 데이터베이스 작업이나 파일 처리와 같이 순서가 중요한 작업에서는 순차적 처리가 필수적이지요.RxJava에서는 이러한 순차적 처리를 보장해주는 concatMap 연산자를 제공해 주는데요. 오늘은 이를 살펴보고,비동기 처리에 사용하는 flatMap과 비교하며 이해해 보겠습니다.1. concatMap 의 특징1-1. 순서보장과 순차적 실행concatMap은 실행순서에 있어서 다음과 같은 특징을 가지고 있습니다.원본 Observable의 항목 순서를 엄격히 유지원본 Observable에서 방출된 각 항목에 대해 생성된 Observable들을 순차적으로 실행이전 Observable이 완료된 후에만 다음 O.. 2024. 11. 3.
RxJava flatMapCompletable 과 flatMap + ignoreElement 조합의 차이 이해하기 오늘은 RxJava에서 Completable을 방출해주도록 변환해주는 연산자인,flatMapCompletable과 flatMap + ignoreElement 조합의 차이에 대해서 알아보겠습니다. 1. flatMapCompletableflatMapCompletable은,Single이나 Observable의 각 항목을 Completable로 변환합니다. 여기서 말하는 Completable은,onComplete 혹은 onError 이벤트만 발생시키는,Observable 을 말합니다. Completable을 방출한다는 것은,flatMap을 통해서 작업을 한 후,반환되는 데이터가 필요하지 않다는 뜻 입니다.이런 종류의 작업으로는 데이터베이스에 저장하는 경우를 생각해 볼 수 있겠네요. Observable.just(.. 2024. 11. 2.
Java 8의 메서드 참조(Method Reference) 문법 이해하기 오늘은 Java8의 메소드 참조 문법에 대해서 알아보겠습니다.이 문법은 RxJava에서도 사용가능한데,이를 사용하면 아주 간결한 표현이 가능해집니다. 1. 메소드 참조이미 이름이 있는 메서드를 람다 표현식으로 사용할 수 있게 해주는 문법입니다.메소드 참조 문법은 '클래스::메소드' 순서로 적어서 사용하는데요.예를 들어, String 클래스의 정적 메소드인 toUpperClass는 아래와 같이 사용할 수 있습니다. String::toUpperCase  그런데 잘 보면, 클래스와 메소드만 있고,인자로 사용되는 변수명 자체가 사라진 것을 볼 수 있습니다. 보통 람다식에서라면 아래와 같이 변수명이 하나 필요한데요.s -> s.toUpperCase() 메소드 참조를 이용하면,컴파일러가 컨텍스트를 통해,필요한 매개.. 2024. 11. 2.
RxJava ignoreElements() 연산자에 대한 이해 오늘은 RxJava의 연산자 중,ignoreElements()에 대해서 알아보겠습니다. 1. ignoreElements()연산자 이름만 보면 이해하기가 쉬운데요.Observable 에서 흘러나오는,데이터를 모두 무시하는 연산자입니다. 그런데, 그냥 무시할꺼면 왜 사용할까요?흘러나오는 데이터가 필요없기 때문입니다.단순히 완료 되었는지, 또는 오류가 발생했는지만, 알고 싶을 때 사용합니다. ignroeElements()를 사용해 주면, 원래의 Observable이 Completable로 변환되는데요.Completable은,onComplete 또는 onError 이벤트만 발생시키는,특별한 유형의 Observable입니다. Observable numbers = Observable.range(1, 5);numbe.. 2024. 10. 30.
Android Studio 에서 기억해야 하는 핵심 단축키 안드로이드 스튜디오를 사용할 때 코드사용에 큰 도움을 주는 단축키들이 많이 있습니다.이런 것들은 자주 사용하면서 기억해 두면 생산성이 높아지는데 큰 도움을 주는데요.이 글에서 정리해 보도록 하겠습니다.1. 선언 및 Usage 찾기 Cmd + B (Usage 찾기)해당 코드가 선언된 곳이나 사용된 곳을 찾도록 도와줍니다. 2.  관련 Action 보여주기Alt + Enter 예를 들어서, Kotlin에서 if문에서 return을 밖으로 꺼내는 것이나,expression body형태로 고칠 때, Action의 도움을 받아서 쉽게 코드를 수정할 수 있습니다.   예를 뿐만아니라, Import 되지 않은 클래스들 같은 경우에 바로 임포트 하는 옵션을 제공해 준다든지,하드코딩된 스트링 값에 대해서, String... 2024. 10. 17.
안드로이드 스튜디오에서 넘치는 글 개행하기: soft wrap 안드로이드 앱을 제작할 때,json파일을 불러와 사용하는 경우도 생기는데요.긴 텍스트가 포함된 JSON 데이터를 안드로이드 스튜디오에서 확인할 때,개발자들은 끊임없이 가로 스크롤을 해야 합니다.이로 인해 가독성이 떨어지고 오타를 찾기가 매우 어려워지죠. 이를 개선하려면, 안드로이드 스튜디오자체에서 개행을 할 수 있도록 해 주어야 하는데요.이를 'soft wrap' 혹은 'word wrap'이라고 합니다.오늘은 이를 안드로이드 스튜디오에서 설정하는 방법을 정리하겠습니다. 1. 설정먼저 안드로이드 스튜디오의 'Preferences'를 찾습니다.단축키는 아래와 같습니다.Command + ,(콤마)  2. Editor 나오는 좌측 네비게이션에서,"Editor > General"로 들어갑니다.그럼 아래와 같이.. 2024. 10. 10.
ifEmpty 와 orEmpty 에 대해서 알아보자 # Kotlin 오늘은 Kotlin 의 ifEmpty 와 orEmpty 에 대해서 정리해 보도록 하겠습니다. 1. ifEmpty Kotlin에는 emptyList인 경우에 디폴트 값을 넘겨줄 수 있는 API가 있는데요. 바로 ifEmpty()입니다. 이 함수의 코드를 보면 아래와 같은데요. isEmpty()로 Collection이 비어있는지를 확인하고, 비어있다면 디폴트 값을 넘겨줍니다. 2023. 5. 30.
CoerceIn, coerceAtMost, coerceAtLeast 범위지정 함수에 대한 정리 # Kotlin 오늘은 Kotlin 에서 값의 범위를 강제할 수 있는, coerceIn, coerceAtMost 그리고 coerceAtLeast 에 대해서 정리해 보겠습니다. 1. CoerceIn 원래 Coerce 라는 단어는 강제로 무언가를 하게 한다는 의미인데요. CoerceIn 은 강제로 어느 범위로 넣게 하겠다는 것 입니다. 인자로 최소값과 최대값을 받는데요. 이 최소값보다 적게나오면, 최소값을, 최대값보다 크게나오면, 최대값을 리턴하도록 강제해주는 API 입니다. 예를 들어서 아래 코드와 같은 경우를 들 수 있습니다. 아래는 Percent 값을 구하는데, distance나 distanceBetween 이 마이너스가 나올 경우에도, 0과 1 사이에서만 값을 주도록 강제해 주었습니다. val distanceInPe.. 2023. 5. 26.
EOFException 발생시키는 empty body 대응 방법 # Retrofit Retrofit 을 이용해서 정상적으로 서버의 데이터를 요청하였을 때, 200 OK를 받았는데도, 서버에서 empty body를 주어서, EOFException 이 발생하는 경우가 있습니다. 오늘은 이것의 대응 방법에 대해서 정리해 보겠습니다. 1. 서버 200 과 EOFException 위에서 언급한 것처럼, 서버에서 200 OK 를 주었는데도, body가 비워져 있어서, EOFException 이 발생할 수 있습니다. 서버에서는 데이터 없으니 "" 를 보내버린 것이구요. 아래와 같이 body는 0-byte가 되어 있습니다. 2023. 5. 25.
MapNotNull 과 MapNotNullTo 에 대한 정리 # null 제거 오늘은 MapNotNull 과 MapNotNullTo 에 대해서 정리해 보도록 하겠습니다. 1. MapNotNull mapNotNull은 엘리먼트에 주어진 transform 연산자를 적용하여서, null 이 나오지 않는 값들로만 list 를 구성해서, 반환해주는 함수입니다. 이름에 map이 있지만, 반환하는 타입은 아래와 같이 List 입니다. null 을 제거해주는 방어연산자라고도 할수 있겠습니다. 2. MapNotNull 예제1 코드를 보면서 이해해 보겠습니다. mapNotNull연산자 안에서, 2로 나누어 나머지가 없이 딱 떨어지는 값은 2를 곱해주고, 그렇지 않은 경우는 null을 리턴하는 조건문을 넣어주었습니다. val numbers = listOf(1, 2, 3, 4, 5, 6) val dou.. 2023. 5. 24.
Broadcast Receiver 등록하고 시스템 이벤트 받아서 처리하기 안드로이드의 시스템은 이벤트가 발생할 때 broadcast를 보내줍니다. 이름이 broadcast이니, 방송을 한다고 해야할까요. 안드로이드 내부적으로 이벤트가 발생을 했다고 알려주는 것인데요, 안드로이드 앱에서, 시스템에게 특정한 이벤트에 관해 관심이 있다고 등록을 하면, broadcast를 수신할 수 있게 되는데요. 오늘은 사용자가 이어폰을 스마트폰에서 빼거나 꽂았을 때, 시스템 이벤트를 받아서 토스트 팝업을 띄우는 방법에 대해서 정리해보겠습니다. 네이버 뮤직 같은 앱들이 헤드폰을 빼거나 꽂았을 때, 플레이를 멈추도록 하는 기능도 broadcastReceiver를 이용했을 거라고 생각이 됩니다. 1. BroadCast 받는 방법 안드로이드의 시스템으로부터는 여러가지 broadcast를 받아서 볼 수 .. 2023. 5. 23.
Vibrator 로 구현하는 안드로이드 진동 앱을 통해 사용자에게 알리는 방법중 진동은 매우 중요한 수단중 하나인데요. 오늘은 Vibrator API를 이용해서 이를 구현하는 방법에 대해서 정리해보겠습니다. 1. Manifest 설정 제일 먼저 해주어야 하는것은 permission을 얻는 것인데요. 다행히도 동적으로 얻어야 하는 수준의 permission은 아닙니다. 아래와 같이, manifest 에서 uses-permission만 VIBRATE에 대해서 정의해주면 됩니다. 2. Vibrator 객체 얻기 가장 먼저 할 일은 Vibrator객체를 얻어오는 것 입니다. 안드로이드 하드웨어와 관련된 클래스들이 그렇듯이, getSystemService 메소드를 사용해서 객체를 얻어와야 합니다. API23 버전(버전 M)부터는 아래와 같이 얻어오구요. 그.. 2023. 5. 23.
List 아이템 부분추출 함수 정리 # take, takeWhile, takeLast, drop, slice, first and last 오늘은 list 나 Sequence에 적용할 수 있는, 아이템을 부분적으로 추출하는 방법에 대해서 정리해 보도록 하겠습니다. 오늘 볼 API에는 다음과 같은 것들이 있는데요. take, takeLast, takeWhile, drop, dropWhile, slice first, last, firstOrNull, lastOrNull 하나씩 보도록 하겠습니다. 1. take api 이름에서 느껴지는 것처럼, 처음 n개의 요소들을 반환해 줍니다. 아래 코드에서는 처음3개를 취하기 위해서, 3을 인자로 넣어주었구요. 결과는 앞의 1,2,3을 반환해 주게 됩니다. val numbers = listOf(1, 2, 3, 4, 5) val result = numbers.take(3) println(result) // 결.. 2023. 5. 15.
compareBy 와 min 그리고 sortedWith 사용방법에 대한 정리 오늘은 리스트를 sorting 할 때 사용할 수 있는, compareBy 와 min 그리고 sortedWith를 사용하는 방법에 대해서 정리해 보겠습니다. 1. 최소값을 찾을 때 2가지 조건을 붙이는 방법에 사용 먼저 CompareBy 와 min 을 사용하는 방법에 대해서 정리해 보겠습니다. 아래 코드에서 사용한 것은 minWithOrNull 인데요. 코드를 먼저 보고 정리해 보겠습니다. compareBy에 두가지 조건 블록이 들어가 있습니다. 이 조건은 아래와 같이 적용됩니다. 먼저 value 가 적은 최소값을 찾고, 다음으로 id가 적은 값을 찾는다 입니다. data class SampleData(val id: Int, val value: Int) val dataList = listOf( Sample.. 2023. 5. 10.
any , contains, none , all, containsAll 에 대한 정리 # Kotlin list 존재여부 확인 오늘은 Kotlin list 의 존재여부를 확인하는 함수인, any, contains, none, all, containsAll 에 대해서 정리해 보도록 하겠습니다. 1. any() 적어도 하나 이상의 매칭되는 아이템이 Collection 에 존재한다면, true 를 없으면 false 를 return 해 줍니다. val list = listOf(1, 2, 3, 4, 5) val result = list.any { it > 3 } println(result) // 결과: true 2023. 5. 6.
StateFlow vs SharedFlow 를 비교해보자 #이벤트 핸들링 오늘은 StateFlow 와 SharedFlow 에 대해서 정리해 보도록 하겠습니다. 1. 기존 글 참조 만약 SharedFlow와 StateFlow 각각에 대한 기본적인 부분들에 대해서 정리하고 싶으시다면, 아래 글들을 참조하신 다음에 이 글을 읽으면 더욱 도움이 될 것 입니다. >> SharedFlow 에 대한 총정리 # Buffer Replay tryEmit Kotlin Coroutine >> mutableStateOf 와 MutableStateFlow 비교 총정리 # collectAsState 2. StateFlow 는 State 변화를 위한 API 2-1. StateFlow 는 이벤트핸들링을 위한 API가 아니다 아래는 Kotlin 이 아닌 Android의 공식문서인데요. 중요한 부분이 잘 설명.. 2023. 5. 6.
SharedFlow 에 대한 총정리 # Buffer Replay tryEmit Kotlin Coroutine 오늘은 Kotlin Coroutine의 SharedFlow 에 대해서 정리해 보도록 하겠습니다. 1. SharedFlow SharedFlow 는 이름에서 알 수 있듯이, Collector 가 여러개인 경우, Collector 들이 emit 된 값들을 동시에 consume 할 수 있도록, Share(공유)되는 Flow 의 API 입니다. fun main() = runBlocking { val sharedFlow = MutableSharedFlow(replay = 1) launch { for (i in 1..5) { sharedFlow.emit(i) println("Emitted: $i") } } launch { sharedFlow.collect { value -> println("Collector 1에서 .. 2023. 5. 4.
Flow 결합연산자 combine , zip , merge 비교 총정리 # Kotlin Coroutine 오늘은 Kotlin Coroutine의 Flow API 중, flow들을 결합해 주는 오퍼레이터인, combine과 zip 그리고 merge에 대해서 총정리해 보겠습니다. 1. combine Combine 은 2개 이상의 스트림 되는 flow 데이터들을, 합쳐서 하나의 flow로 흘려보내 주는 API입니다. 2개의 스트림을 합쳐주는 것은 알겠는데, 각각의 데이터들이 다른 시점에 나올 때는 어떻게 되는 것일까요? 아래 공식문서의 설명에 따르면, 둘 중 가장 최근에 방출되는 값이 있으면, 그 값을 기준으로 합쳐진 flow 를 방출해 줍니다. 단순히 2개의 flow를 합쳐준다고만 이해해서는 안 되고요. 2개의 flow 중 어느 하나에서 아이템이 방출되면, 최근 2개의 flow를 합쳐서 방출해 줍니다. 좀 더.. 2023. 5. 3.
onEach vs onStart 비교 정리 # Kotlin Coroutine Flow 오늘은 Kotlin Coroutine Flow의 onEach 와 onStart 에대해서 정리해 보도록 하겠습니다. 1. onEach flow 에서 아이템이 흘러나올 때 마다, 실행하도록 해야하는 코드가 있다면, 이 연산자를 사용하는 것이 좋습니다. upstream 즉 위의 flow 에서 흘러나오는 값을 그대로 전달해 주기 때문에, 흘러나가는 데이터에는 영향을 주지 않습니다. 코드를 보면서 이해해 보도록 하겠습니다. val flow = flowOf(1, 2, 3, 4, 5) flow .onEach { item -> println("Item emitted: $item") } .map { item -> item * 2 } .collect { result -> println("결과: $result") } 2023. 5. 3.
Destructuring declaration 에 대해 알아보자 # 구조분해 선언 Kotlin 오늘은 Destructuring declaration 에 대해서 정리해 보도록 하겠습니다. 1. Destructuring declaration 한국말로는 구조파괴 또는 분해 선언이라고 할 수 있는데요. 단 한줄로, 객체의 여러 프로퍼티들을 한번에 선언하게 해주는 문법입니다. 코드가 짧아지고, 가독성도 향상됩니다. 2. 구현 2-1. 구현준비 실제로 코드로 보면서 이해하는 것이 빠를텐데요. 다음과 같은 간단한 Student 클래스가 있다고 가정해 보겠습니다. data class Student(val name: String, val age: Int) 이제 위의 데이터 클래스로 객체를 아래와 같이 만들어줍니다. val student = Student("Ive Shim", 23) 2023. 5. 1.
Kotlin Escape 에 대한 정리 # RawString Escaped String Literal 오늘은 Kotlin 의 String Literal 에서 사용되는 Escape 규칙에 대해서 정리해 보겠습니다. 1. Escape Kotlin String Literal 에서 Escape는 "\" 를 이용해주면 되는데요. 원래는 그냥 사용하면 제대로 전달이 안되지만, 아래와 같이 사용해주면 그대로 전달될 수 있습니다. 특히나 따옴표(Single Quote)나 쌍따옴표(Double Qoute) 같은 경우 꼭 알아두어야 합니다. 기호 의미 \" Double quote \' Single quote \\ Backslash \n Newline \r Carriage return \t Tab 2023. 4. 30.
Kotlin GroupBy 구현과 정리 # List 그룹핑 오늘은 Kotlin의 GroupBy 에 대해서 정리해 보겠습니다. 1. GroupBy API 우선 해당 API의 코드를 가볍게 보고 가도록 하겠습니다. 아래에서 보듯이 GroupBy는 Iterable 타입의 collection 에서, 전달되는 특정한 기준을 Map의 Key값으로 해서, 그에 해당하는 데이터들을 List로 묶어서 Value에 넣어줍니다. 2023. 4. 28.
getOrNull 과 getOrElse 에 대한 정리 # List Kotlin Kotlin에는 편리한 함수들이 정말 많은데요. 오늘은 Kotlin 의 getOrNull 과 getOrElse 에 대해서 정리해 보도록 하겠습니다. 1. getOrNull () 과 getOrElse() 1-1. getOrNull 주어진 Index에 대해서 엘리먼트가 있으면 반환해주고, 해당 index가 범위내에 없으면 null 을 반환해 주는 Kotlin Collections 의 list 입니다. 2023. 4. 28.
SharedPreference 로 간단한 데이터 저장하기 # Android 안드로이드 개발을 하면서 간단한 key-value 형태의 값들을 앱안에 저장할 때가 있는데요. 예를 들면, 앱의 글자 크기설정, 알람 온오프 같은 값입니다. 그런데, 이럴때마다 DB를 사용하는 것은 너무나 무거운 일인데요. SharedPreference를 사용하면 좀더 가볍고, 쉽게 해결할 수 있습니다. 1. SharedPreference 는? SharedPreference는 비교작 작은 크기의 키-밸류값을 읽고 쓸수 있도록 Android Framework에서 제공해주는 기능입니다. 위에서 애기한것처럼, 설정 값등을 저장 하는데 많이 사용 하구요. 경우에 따라서 private하게 사용하거나, share될 수 있도록 할 수 있습니다. 2. SharedPreference 초기화 먼저 SharedPrefere.. 2023. 4. 27.
Kotlin Pair 와 Map 함수 이용해서 데이터 가공하기 오늘은 Kotlin 에서 Pair()와 Map() 함수를 이용하는 방법에 대해서 정리해 보겠습니다. 1. Pair 데이터 먼저 아래와 같은 Pair()객체를 list 에 여러개 있다고 가정해 보겠습니다. val testList = listOf(Pair("one", 1), Pair("two", 2), Pair("three", 3)) 참고로 to 키워드를 사용하면 Pair()생성자 형태를 사용하지 않고도 Pair 객체를 만들수 있습니다. Kotlin에 있는 infix함수라는 개념인데, 보통 사용하는 점(.)이나 괄호() 를 사용하지 않고 함수를 호출하게 해줍니다. val testList = listOf("one" to 1, "two" to 2, "three" to 3) 2023. 4. 26.
Room DB 에서 검색 구현하기 # Like ExactMatch SQL 오늘은 RoomDB에서 검색하기를 구현하는 방법에 대해서 정리해 보겠습니다. entity, dao 등 RoomDB에 관한 기본적인 내용은 아래 글을 참조해 주세요. >> Room DB 사용방법 총정리 # Android SQLite 1. 검색을 위해 준비한 데이터 검색을 구현하기 전에 먼저 데이터가 저장되어 있어야 하는데요. 아래와 같이 아주 간단한 데이터가 있다고 가정해 보겠습니다. 표에는 안적혀 있으나, Database명은 "student" 로 하였습니다. studentId Name 1 Aileen lee 2 Eyenie park 3 Ive Kim 2. 검색을 위한 DAO 작성 2-1. 단순한 like 검색 위의 데이터에서 이름으로 학생데이터를 검색하기 위해서는 아래와 같이 Dao를 작성해 주어야 합니.. 2023. 4. 24.
getLaunchIntentForPackage 로 다른 앱을 실행 하는 방법 # query Android 11 오늘은 안드로이드 앱에서 다른 앱을 launch 시키는 방법을 정리해 보도록 하겠습니다. 1. Query Manifest 적용 Android11(API30)이 발표된 이래로, 앱내에서 다른 앱을 실행하는 경우 Manifest에서, 다른 앱에 대한 패키지 명을 명시해 주어야만 합니다. 예전에는 없었던 작업이므로, 간혹 오래된 앱들은 이것이 선언되지 않아서, 기능이 작동하지 않을 수 있습니다. 혹시 잘 되던 기능이 않되고 있다면 이 부분을 체크해 주어야 합니다. manifest 에 선언하는 것이므로, Enum 클래스를 사용할 수 없습니다. 하드코딩해야 하므로, 테스트를 반드시 해 주어야 합니다. ... ... 2023. 4. 20.
Coroutine suspend 동작에 관한 좋은 예와 잘못된 예 # 비동기 오늘은 Coroutine 은 기본적으로 비동기를 기본으로 합니다. 그렇기에 비동기 블록이 suspend 되어서 결과값을 받아서 실행해야 할 경우는, suspend 함수를 위치시킬 때 생각을 해야 합니다. 그렇지 않으면 예상치 못한 동작을 보게되는데요. 오늘은 suspend 함수를 이용해서 Coroutine을 잘 사용한 예와 잘못 사용한 예를 점검해 보겠습니다. 1. suspend 가 제대로 동작하지 않는 잘못된 케이스 우선은 코드를 보도록 하겠습니다. 아래에서 launch 블록바깥에 결과를 얻어서, print 하는 것이 의도인데요. 실제로 실행해 보면, result에 값이 담기기 전에 지나쳐 버립니다. suspend fun fetchData(): String { delay(2000) return "dat.. 2023. 4. 18.