Development/Android

Scope Builder- 다른 builder들에서 제공하는 Coroutine Scope 외에도, Coroutine Scope 빌더를 활용하여 고유한 scope을 선언할 수 있다. - coroutineScope는 자식 Coroutine 들의 실행이 모두 완료될 때까지 종료되지 않는 Coroutine Scope을 생성한다. - runBlocking의 경우에는 대기를 위해 현재 Thread를 Block 시키는 반면, coroutineScope는 다른 작업이 수행될 수 있도록 작업 중이던 스레드의 자원 사용을 해제한다는 차이가 있다.fun main() = runBlocking { doWorld()}suspend fun doWorld() = coroutineScope { // this: Coroutine..
Coroutine이란?- Coroutine은 일시정지 연산을 위한 인스턴스이다. 이것은 코드의 나머지 부분들과 동시에 실행되는 코드 블록을 가진다는 점에서 스레드와 개념적으로 비슷하다. 하지만, 코루틴은 특정한 스레드에 종속되어 실행되지 않으며, 하나의 스레드에서 일시정지(suspend) 되었다가 다른 스레드에서 재개(resume)될 수 있다. - 일반적인 스레드와 달리 코루틴은 작은 비용으로 생성되고, 필요할 때만 작업을 실행하거나 중단할 수 있기 때문에, 리소스 효율성이 매우 뛰어나다. - 코루틴의 장점으로는 간결한 문법과 취소, 중단, 시간 초과에 대한 제어가 유연하다. Coroutine 핵심 구성 요소- 중단 가능한 suspend 함수 : Coroutine 안에서만 호출 가능suspend fun ..
- 둥근 모양 테두리 이미지를 사용하는 간단한 방법이 있다. - material에서 제공하는 ShapeableImageView를 사용하는 것이다. 스타일만 지정해 주면 원하는 모양의 이미지뷰를 구성할 수 있다. - 먼저 values - styles.xml에 RoundedCornerImage에 대한 style을 선언한다. - 그리고 XML에서 ShapeableImageView를 선언하고, AppearanceOverlay 요소로 생성한 style을 적용한다.- strokeColor, storkeWidth 또한 설정 가능하다.
- 안드로이드에서 화면 회전 시 이루어지는 라이프 사이클은 다음과 같다.onPause() onStop() onDestroy() → 회전 발생 → onCreate() onStart() onResume()- 완전히 재생성되는 것이기 때문에 변수들도 초기화된다. - 따라서 사용자 입장에서는 변수 초기화로 인해 단지 화면 회전만 보기 편하게 바꿨을 뿐인데 UI가 변경되어 버리는 증상을 경험할 수 있다. - 애초에 ViewModel 기반으로 데이터가 관리된다면 걱정할 일이 없겠지만 그렇지 않은 경우에는 Instance State를 통해 변수 값을 복원할 수 있다. - Activity의 onSaveInstanceState와 onRestoreInstanceState 두 가지 함수를 구성한다. - 각 함수는..
- 이전에 브로드 캐스트 리시버로 자정이 되면 위젯을 갱신하는 로직을 구현했었다. - 그런데 이때 예약을 위해 사용된 setExact()가 반드시 알람 권한을 획득해야만 하는 함수인데 사용자가 알람 권한을 허용하지 않고 앱을 사용하다 보면 위와 같은 Exception이 발생하는 것이다. - 사실 알람 설정 기능이 아니고, 이미 다른 영역에서 권한 처리를 받도록 구성되어 있으며, 해당 기능은 백그라운드에서도 동작해야하는 부분이라 알람 권한 없이도 기능이 동작하도록 구성했어야 한다. - 이를 위해 setAndAllowWhileIdle()을 사용했다. 권한 필요 없이 Doze에서도 울릴 수 있는 유일한 대안이다. - 하지만 setExact()와 다르게 정확한 시간을 보장하지는 않는다. 약 1~2분 정도 차이가..
- 의존성 주입이라는 개념이 있다. 객체가 필요한 의존 객체를 외부에서 주입받아 사용하는 설계를 말한다. - 보통 일반적으로 수동적 의존성 주입 처리가 진행된다. 하지만 지연 초기화, nullable 처리, 코드 중복량 증가에 대한 문제점들이 시간이 지날수록 드러난다. - 이런 문제점들을 줄이기 위해 DI를 컴파일 시점에서 처리해 런타임 성능을 최적화하고, 어노테이션으로 객체 간 의존 관계를 관리할 수 있는 라이브러리 Hilt가 있다.https://developer.android.com/training/dependency-injection/hilt-android?hl=ko Hilt를 사용한 종속 항목 삽입  |  App architecture  |  Android Developers이 페이지는 Cloud..
- 캘린더형 위젯을 지원 중인데, 자정이 지나도 위젯이 갱신되지 않고 전날 날짜가 그대로 유지되는 현상이 발견되었다. - 자정이 되는 시점을 감지하고, 위젯을 update 시켜주는 로직 구성 작업이 필요했다.  - 안드로이드 4대 컴포넌트 중 하나인 BroadcaseReceiver를 사용하면 된다.What are the four components of an android application?ActivitiesServicesBroadcast ReceiversContent Providers- 자정 시간을 알람 시간으로 등록하고 해당 시간이 되면 PendingIntent를 통해 리시버를 동작시킨다.class MidNightReceiver: BroadcastReceiver() { override fun..
- 보통 뷰에 특정 배경색 또는 테두리 효과를 주입하는 것은 아래처럼 drawable XML 소스를 구현하면 된다.  - 하지만 테두리의 경우 그러데이션을 자체적으로 지원하지는 않은 것으로 확인되어 Paint를 활용해 그려서 커스텀 뷰를 구현하는 작업을 진행했다.class GradientStrokeButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatImageButton(context, attrs, defStyleAttr) { private var cornerRadius = 0f private var bord..
- 자사 서비스에서 Realm DB를 활용하고 있다. - Realm DB는 빠르고 가벼운 로컬 데이터 저장을 위한 객체 기반 데이터베이스이다.  - Realm DB의 객체로 리스트를 구성할 때는 RealmRecyclerViewAdapter를 이용하여 구성할 수 있다. - 내부 구성은 일반 RecyclerView와 크게 다르지 않다. 하지만 getItem 등의 함수가 RealmDB 자체에서 오리지널 인스턴스를 가져오는 방식으로 동작한다./** * Returns the item in the underlying data associated with the specified position. * * This method will return {@code null} if the Realm instance has ..
- 기존 프로젝트 내에 인앱 결제 관련 로직이 너무 노후화되어 있었고, 함수도 분산되어 있어서 관리하기가 난해했다. - 최근에 모듈을 최신화하면서 주요 함수를 BillingManager라는 싱글톤 object로 정리했는데, 그 내용을 기록해 본다.결제 모듈 초기화object BillingManager { private var billingClient: BillingClient? = null /** * 결제 모듈 초기화 완료 여부 */ fun isReady(): Boolean { val client = this.billingClient ?: return false return client.isReady }- 결제 모듈 초기화 완료 여부를 확인하는..