android

    [Android] ViewModel에서 LiveData와 StateFlow의 권장 사용 방법

    안드로이드 프로젝트를 개발하면서 ViewModel을 사용할 때, LiveData 혹은 StateFlow를 활용하여 데이터 변경을 관찰하고 UI에 반영한다.이때 Mutable 변수는 private으로 설정하고 이름 앞에 _를 붙이고, 외부에 노출되는 변수는 Immutable로 사용하는 것을 흔히 볼 수 있다.일반적인 코드 컨벤션이라고 생각할 수도 있지만, 좀 더 생각해 보면 객체지향 설계 원칙과 클린 코드 관점에서 중요한 이유가 있다.권장 이유1. 캡슐화 (Encapsulation)캡슐화는 객체지향 설계의 기본 원칙 중 하나로 데이터를 직접 접근하지 못하게 하고, 데이터에 대한 접근을 제한하며, 변경을 메서드를 통해서만 할 수 있도록 한다. MutableLiveData나 MutableStateFlow를 p..

    [Android] OS 10 이상에서 알림 갯수 제한 문제 해결

    안드로이드 OS 10부터 특히 삼성 단말에서는 알림을 24개까지만(삼성 단말 기준) 노출할 수 있고, 그 이후에 생성된 알림은 무시되는 문제가 발생할 수 있다. 이를 해결하기 위해 가장 오래된 알림부터 순차적으로 삭제하면서 새로운 알림을 보여주는 방법을 공유한다.문제 상황알림이 24개를 초과하게 되면 새롭게 생성되는 알림은 사용자에게 표시되지 않는다. 이는 새롭게 발생되어야 하는 알림이 사용자에게 전달되지 않는 문제를 야기할 수 있다.해결 방법가장 오래된 알림부터 삭제하고 새로운 알림을 추가하는 방법으로 해결해보려고 한다.이를 위해 알림 ID를 관리하고, 알림을 생성할 때마다 알림 ID를 순환시키는 방식으로 오래된 알림을 삭제한다.구현 방법1. 알림 ID 관리알림 ID를 관리하기 위해 큐(Queue) 자..

    [Android] RecyclerView 성능 최적화를 위한 ListAdapter 살펴보기

    요즘 RecyclerView를 위한 Adpater를 구현할 때는 주로 RecyclerView.Adapter보단 ListAdapter를 상속받아 구현한다.ListAdapter는 androidx.recyclerview 패키지에 소속되어 있고 RecyclerView.Adapter를 확장한 클래스로 AsyncListDiffer를 통해 리스트 데이터를 비교하여 반영한다.ListAdapter의 생김새를 알아보자.public abstract class ListAdapter extends RecyclerView.Adapter { final AsyncListDiffer mDiffer; protected ListAdapter(@NonNull DiffUtil.ItemCallback diff..

    [Android] Notification 커스텀하기

    기본적으로 여러 Android 버전에서 알림이 잘 보이도록 하려면 표준으로 제공하는 Notification 템플릿을 사용하는게 가장 좋다. 하지만 요구사항에 의해 기본 템플릿 말고 직접 커스텀한 레이아웃으로 Notification을 구현할 수 있다. 중요한 점은 직접 커스텀한 레이아웃을 적용하기 위해 Notification style 속성에 NotificationCompat.DecoratedCustomViewStyle을 적용해주어야 한다. 이제 순서대로 커스텀 Notification을 적용하는 방법을 알아보자. NotificationCompat.Builder로 기본 Notification을 생성한다. 생성한 Notification 객체의 setStyle()을 호출하여 NotificationCompat.D..

    [Kotlin] runCatching

    runCatching은 코틀린 1.3 버전부터 지원된 캡슐화 블록으로 블록의 실행 결과가 Result의 형태로 리턴된다. 또한 실행 결과에 따른 프로퍼티, 함수들을 사용하여 유연한 이벤트 스트림으로 처리하여 가독성 있는 코드를 구현하는데 큰 도움이 된다. runCatching 예시 val name: Result = runCatching { //String을 리턴하는 작업 "JMJ94" }.onSuccess { it: String -> it }.onFailure { tr: Throwable -> println("$tr") } runCatching은 실행 결과에 따른 프로퍼티를 제공한다. isSuccess runCatching 블록의 실행이 별문제 없이 성공한다면 result는 true고 문제가 발생한 경우..

    [Android] Activity와 Fragment

    Activity Activity는 안드로이드의 컴포넌트 중 하나로 사용자와 상호작용을 담당하는 단일화면으로 위 이미지와 같은 Lifecycle을 갖는다. Activity의 생성부터 종료되기까지 일련의 모든 이벤트들에 대한 콜백을 지원해주기 때문에 상황에 맞는 로직을 구현할 수 있다. 이러한 이점을 통해 각 상태별로 리소스를 관리 포인트를 고려하여 메모리 누수에 대한 위험을 방지해야 한다. Activity LifeCycle의 각 콜백에 대해 알아보자 onCreate() - 시스템이 Activity를 생성할때 실행하는 콜백으로 해당 Activity가 실행되면서 한 번만 실행해야 하는 로직들을 이곳에 구현하면 된다. 예를 들면 View 바인딩 작업이나 ViewModel을 연결하는 작업들이 이곳에서 이루어지면 ..