Development/Android

- 안드로이드에서 화면 회전 시 이루어지는 라이프 사이클은 다음과 같다.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 }- 결제 모듈 초기화 완료 여부를 확인하는..
- 페이징 라이브러리를 사용한 것은 아니고, 파라미터로 page: Int를 보내고 response로 hasNext: Boolean을 수신받을 수 있는 형태의 api에서 페이징을 자체 코드로 간단하게 구현한 예시다.상단 구성 - Scaffold 구조로 상단에 TopAppBar를 가지고 내부 content로 리스트를 가지는 화면에서 페이징을 구성했다.Scaffold(topBar = { TopAppBar(modifier = Modifier.padding(start = 12.dp), title = { Text() }, navigationIcon = { IconButton(modifier = Modifier .size..
((Vibrator)AppCore.context.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(10);- 기존 코드에서 사용하던 디바이스 진동 효과를 발생시키는 vibrate 코드가 deprecated 되어 있었다. - 10m/s 동안만 일시적으로 진동을 울리는 코드인데, Android O(26)부터 아래와 같이 수정이 필요하다.Vibrator vibrator = (Vibrator) AppCore.context.getSystemService(Context.VIBRATOR_SERVICE);if (vibrator != null && vibrator.hasVibrator()) { // 진동 기능이 있는지 확인 vibrator.vibrate(Vibrat..
Places Api (New) 활용- 사내 프로젝트에 예전부터 Places SDK가 적용되어 위치 검색 기능을 담당하고 있었는데, 어느 시점부터 아래와 같이 오류가 표시되는 지역들이 증가하기 시작했다.- Google Places API(신규)는 기존 Places API를 대체하는 서비스로, 장소 검색, 자동완성, 상세 정보 조회, 좌표 변환 등의 기능을 제공한다. 그리고 데이터가 등록된 장소 개수 자체도 훨씬 많은 것으로 알고 있다. - 기존에 사용하고 있던 API Key가 있다면 Places Api (New)를 사용으로 설정한 뒤, 제한 목록에 추가해 주면 된다.- 신규, 기존 상관없이 적어도 아래 목록은 키 제한 API 목록에 포함시켜야한다. 그렇지 않다면 권한 거부 오류가 발생한다.Places SD..
SeungYong.Lee
'Development/Android' 카테고리의 글 목록 (10 Page)