Android

api 통신에 대한 에러 발생 시, 해당 통신에 대한 Reqeust Body를 추출하여 사용자가 어떠한 값을 보냈는지 파악할 필요가 있다. @Body 또는 @Field 형식으로 보내는 경우에 대해 OkHttpClient에서 값을 추출하는 로직을 구성해 봤다. private fun extractBodyStringFromRequest(request: Request): String { return if (request.body is FormBody) { //Field type val field = mutableMapOf() val formBody = request.body as FormBody for (i in 0 until formBody.size) { field[formBody.name(i)] = form..
달력형 위젯을 구현 중, Background ImageView에 디자이너분이 제작해 주신 테마 이미지를 Bitmap으로 삽입하던 중 다음과 같은 오류가 발생했다. java.lang.IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage (used: 7474416, max: 6432000) 무슨 오류인가.. 확인해 보니 Bitmap 메모리 사용량이 한도를 초과한 것이다. 이미지 크기와 해상도가 상이하기 때문에 충분히 발생할 수 있다고 생각했다. 위젯에 최적화된 이미지를 다시 제작하기 전까지는 임시로 크기를 줄여서라도 사용하기로 결정했다. fun getBitmapSize(file: File): Siz..
개발을 진행하면서 App에 특정 테마 색상을 지정하고 싶은 경우가 있다. 그때 테마가 어두운 계열인지 밝은 계열인지에 따라 Full Screen이 아닌 이상 Status Bar와 Navigation바 아이콘 색상을 테마 색상에 대해 반전시키는 것이 좋다. val isDarkTheme = AppTheme.isDarkTheme() //Custom function to check if it is dark theme WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = !isDarkTheme WindowInsetsControllerCompat(window, window.decorView).isAppearanceLi..
Moshi - API 통신 시, JSON과 객체 사이의 직렬화 및 역직렬화를 간단하고 신속하게 해주는 라이브러리 - 내부 동작에서 Reflection 사용 Reflection : 자바의 기능 중 하나로, 클래스나 인터페이스의 정보에 직접 접근 가능케 하는 API을 일컫는다. 직렬화 : 특정 데이터를 다른 CPU로 보내기 전 통신이 가능하면서도 나중에 재구성이 가능한 포맷으로 환해주는 행위 역직렬화 : 직렬화된 데이터를 다시 객체 형태로 변환하는 행위 JSON 처리 @JsonClass Annotation : JSON Object에 대응되는 역할을 한다. 해당 Annotation은 JSON Object에 대응되는 클래스 생성 시 상단에 붙인다. 파라미터로 들어가는 generateAdapter를 true로 S..
Enum Class - 특정 상태를 지정하는 상수들을 클래스 내부에 고유 값으로 만들어 사용 - 소스코드의 가독성을 높이는데 기여한다. - 상수 값의 타입 안전성을 보장한다. enum class EnumTest { Naver, Google, Yahoo, Daum } fun getPortalType(s : String) { when (s) { "naver" -> EnumTest.Naver "google" -> EnumTest.Google "yahoo" -> EnumTest.Yahoo else -> EnumTest.Daum } } - 각 열거 자료형은 enum 클래스의 인스턴스이기 때문에 다음과 같이 초기화가 가능하다. enum class Color(val rgb: Int, val colorName: Str..
Singleton Pattern - 어떤 클래스의 인스턴스는 오직 하나임을 보장하며, 해당 인스턴스를 전역적으로 접근 가능케하는 패턴 - 고정된 메모리 영역을 가지기 때문에 메모리 사용의 효율성 증가 - object 키워드를 통해 간단하게 패턴 생성 가능 Java의 Static 활용 시에는 호출 시점에 인스턴스가 생성되지만, Kotlin의 Object는 프로세스가 메모리 상에 올라가는 순간 바로 생성된다. 이는 즉, 굳이 사용되지 않을 때에도 메모리에 인스턴스가 존재하기 때문에 어떤 경우에는 주의할 필요가 있다. Object - 클래스 외부에서 선언되며 별도의 객체 생성 없이 즉시 호출이 가능하다. - 하나의 객체만 접근 시점에 생성되므로 생성자가 없는 클래스만 사용 가능 - 특정 초기화를 위해서는 in..
서버와의 협업 중, 어떤 사유로 반환 값이 empty body가 수신될 때, 제목과 같은 Exception이 발생했다. 명시한 data class와 별개로 해당 상황에 대한 response body convert 처리가 필요한 것으로 파악된다. 따라서 다음과 같이 Custom Converter Factory를 생성하여 Retrofit Builder에 반영해주어야한다. class EmptyResponseConverterFactory : Converter.Factory() { override fun responseBodyConverter( type: Type, annotations: Array, retrofit: Retrofit ): Converter { val delegate = retrofit.nextR..
안드로이드 시스템 환경설정에는 애니메이션 끄기 여부를 선택할 수 있는 기능이 있다. 해당 토글을 ON 처리하면 디바이스 전반적으로 애니메이션 기능이 제거된다. 하지만 애니메이션이 사용된 앱 같은 경우, 정상적인 View 동작을 위해 분기처리가 필요한 경우가 있다. 이럴 때, 다음 코드를 통해 애니메이션 활성화 여부를 확인할 수 있다. fun isAnimationEnabled(context: Context): Boolean { var isEnable = true try { isEnable = Settings.Global.getFloat(context.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE) != 0f } catch (e: Settings.Set..
EditText에 하이픈(-)이 자동 추가되도록 TextWatcher에서 지원하는 PhoneNumberFormattingTextWatcher를 사용할 수 있다. 아래 Listener를 등록만 해도 자동으로 전화번호 형식이 입력되는 것을 확인 가능하다. binding.numberEdit.addTextChangedListener(PhoneNumberFormattingTextWatcher())
안드로이드의 Activity에서는 navigationBarColor를 다음과 같이 지정해줄 수 있다. activity.window.navigationBarColor = getColor(R.color.white) 그런데, Activity 수준에서 색상을 지정해도 Bottom Sheet를 열면 적용되어 있지 않아 별도로 지정이 필요하다. 다음과 같이 override되는 Dialog 객체를 통해 지정 가능하다. override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) dialog.window?.navigationBarColor = activity.get..