안드로이드

Android

Android Room 오적용기(misapplied)

먼저 이번 글에서는 코드가 등장하지 않는다. 이번 오적용기가 나에겐 나름 Room을 제대로 사용해본 경험이라 작성해둔 코드가 아쉽기도 하다. 하지만, 언젠가는 갈아엎어야 될 코드가 되어버렸다. 왜 그렇게 됐을까? 현재 상황 파악의 중요성내가 연동해야할 백엔드는 어떤 상황인가?를 너무 간과했다. 대부분 앱 서비스는 회사에서 서버를 두고 앱이 해당 서버와 통신하게 된다. 그리고 해당 백엔드에서 가져온 데이터로 로컬 DB를 구성해 앱에서 사용한다. 하지만, 나의 경우는 각각 지역의 로컬 서버가 존재하고해당 서버에서 DB 파일을 다운로드받아 Room으로 사용하는 것이었다. 더욱 심화되는 문제와 해결 불가능한 상황까지각 로컬 서버는 모두 같은 Table 버전을 갖고 있을 것이라 생각했었다. 하지만 로컬 서버들은 ..

Android

Android AES-128 Encryption with Random IV in Java

사실 이 문제는 회사에 들어와 가장 먼저 고민했던 문제였다. 로그인 시, 아이디와 패스워드를 암호화해 전송해야 했기 때문이다. 전에 Google Play Console 여기저기를 누르다보니 SHA 방식의 암호화를 지나치듯 본 기억이 있었다. 짧은 AES 방식 소개하지만 SHA는 복호화할 수 없는 방식이기에 AES 방식을 사용하기로 했다. AES 암호화 방식은 key 값의 길이에 따라 바뀌는데 16바이트이면 AES-128, 32바이트이면 AES-256이 된다. 대신 IV(Initialization Vector)의 길이는 AES-128, AES-256 둘 모두 16바이트로 동일하다. Random IV를 적용해보기여기서 재밌는 기능을 하나 추가해보자. 바로 IV를 매번 random하게 생성하는 것이다. 그리고..

Android

Android Progressbar not spinning(not animated)

오늘은 저번 글에 이어 저사양 디바이스를 타겟팅해 앱을 개발하던 중 발견하게 된 증상을 공유해본다.(갤럭시와 같은 휴대폰 중 저사양 디바이스가 아닌 안드로이드 TV용 박스를 가지고 개발했다.) 나는 이 증상을 처음 보고 적잖이 당황했었다. 뭐랄까.. 지금까지 알던 세상이 부정당한 느낌..? 항상 되던 것이 안되니 말이다. 원인이런 끔찍한 현상이 생긴 원인이 뭘까? 바로 Animation 길이 배율 설정(Animator duration scale)이다. 평소에는 신경도 안 쓸 설정 메뉴이지만, 저사양 기기에서는 성능을 올리기 위해서인지 꺼져 있었다. 이거... 어디 있는 메뉴일까? 정답은 개발자 옵션에 있다. 기본 설정이 1x로 되어있는 디바이스가 대부분일텐데 내가 개발했던 녀석은 사용 안함이 기본이었다...

Android

Android White Screen Before Splash Screen Resolved

이번 글은 저사양 기기를 타겟팅하여 개발하던중 발견하게된 이슈이다.문제의 시작권한 처리를 위해 회사 로고가 중앙에 들어간 스플래시 화면을 추가했다.해당 앱은 기기 설정에 상관없이 다크 테마 색상이 적용된 것처럼 color resource가 설정되어 있었다.(스플래시 화면도 마찬가지이다.)그런데 앱을 시작하면 흰색 화면이 보이고 나서 스플래시 화면이 보였다.문제 해결가장 먼저 해결법을 찾게된 글은 아래 링크였다.https://github.com/crazycodeboy/react-native-splash-screen/issues/338 White screen before splash screen · Issue #338 · crazycodeboy/react-native-splash-screenAfter sev..

Android

Android APK Decompile(Proguard 적용 확인)

필요해진 배경“요즘 다 앱 번들(.aab)로 배포하고 테스터 초대하지 않나?”라고 생각할 수 있지만 나는 이번에 APK 형태로 업체에 설치파일로만 배포하는 상황이 생겼다.그래서 스플래시 화면에서 설치 비밀번호가 없으면 다음 화면으로 넘어가지 않도록 했고이와 더불어 멋대로 Decompile 되지 않도록 Proguard 난독화를 사용했다.물론 난독화 설정을 켜고 릴리즈 빌드를 하면 적용이 될 거라 생각했지만 혹시 모르니 확인하는 과정을 거쳤다.이제 시작해보자.가장 먼저 내가 참고한 블로그 링크를 첨부한다.https://chelsea-kbj.tistory.com/9 [Mac] 안드로이드 APK 파일 Decompile 하기저는 주로 쇼핑몰 앱 개발 및 운영을 하는 아이폰/안드로이드 앱 개발자입니다. 요즘 보안에..

Language/Kotlin

Implement Coroutines Retry

이번에는 코루틴으로 재시도하는 동작을 구현해보려한다. 주로 "API 요청을 보내고 정상적인 응답이 오지 않으면 최대 n회 재시도한다" 같은 시나리오에 유용하게 사용할 수 있다. 샘플 코드와 함께 살펴보자. viewModelScope.launch { val retryNumber = 2 try { repeat(retryNumber) { try { loadRecentVersion() return@launch } catch (e: Exception) { e.printStackTrace() } } loadRecentVersion() } c..

Language/Kotlin

Implement Coroutines Timeout

이번에는 코루틴에서 타임아웃 기능을 구현해보자. 너무 뜬금없이 타임아웃 얘기를 해서 살짝 첨언해보자면,API request를 보내고 response에 기본 타임아웃이 있듯 타임아웃을 만들어보자는 것이다. 따라서 내가 소개할 메소드는 withTimeout, withTimeoutOrNull 총 2가지이다. 가장 큰 차이는 예외 발생 여부이다.(여기서 말하는 예외는 TimeoutCancellationException으로 기타 다른 예외들은 당연히 발생할 수 있다.) 코드와 함께 살펴보도록 하자. withTimeoutfun main() = runBlocking { try { withTimeout(1000L) { // some behaviors } } catch(e: TimeoutCance..

Language/Kotlin

async CoroutineBuilder Introduction

이번 글에서는 저번 글에서 빼먹었던 async 코루틴 빌더의 필요성과 어떤 녀석인지 소개해보려고 한다. async CoroutineBuilder 필요성 이해하기대체 이 async라는 코루틴 빌더가 존재하는 이유가 뭘까? 이 빌더를 설명하는 글을 보면 대부분 "결과를 반환받는다" 또는 "실행이 완료되기를 기다릴 수 있다"는 멘트가 적혀있다. 나같은 초급 개발자는 "그게 그렇게 다른점인가?"하고 생각할 수 있다. 뭐 결과를 반환받는 것은 다른 점일 수 있지만,실행이 완료되기를 기다리는 건 launch 코루틴 빌더로도 join() 메소드를 사용하면 가능하기 때문이다. 코드로 launch와 비교해보기어떤 MutableList 원소를 채워넣는 상황이라고 가정해보자. 그리고 두 코드 블럭을 비교해보자. 과연 어떤 ..

Language/Kotlin

Coroutines 기본적인 에러 처리하기(feat. try-catch)

나는 지금까지 예제를 사용하면서 네트워크 작업을 예로 들었다. 게다가 해당 작업이 무조건 정상 동작하는 시나리오로만 공부했다. 만약, 네트워크 작업을 수행할 때 HTTP 500번대와 같은 에러가 발생한다면 어떻게 처리해야할까? 이 에러 상황을 처리하지 않고 앱을 실행하게 되면 바로 크래시가 난다. 그럼 어떡함?제목에서 거의 스포가 되었는데, 정말 간단히 처리하는 방법이 하나 있다. try-catch를 사용하는 것이다. fun performNetworkRequest() { viewModelScope.launch { try { val recentVersions = getRecentVersions() } catch (e: Exception) { e.printStack..

Language/Kotlin

Coroutines의 Main safety

이번 글에서는 Coroutines가 어떻게 main-safety하게 동작하는 지에 대해 설명해보려한다. 먼저 안드로이드 ViewModelScope에서 실행되는 코루틴은 기본적으로 main thread에서 실행된다. 이는 매우 합리적인 이유가 있는데 우리는 ViewModel에서 UI 관련 작업을 자주 수행하기 때문이다. 우리가 ViewModel에서 아래와 같은 함수를 실행한다고 가정해보자.fun performNetworkRequest() { viewModelScope.launch { val recentVersions = getVersions() // this is a suspend function }} 이렇게 네트워크 작업을 Retrofit으로 수행할 때, main thread blocking..

BonusTrack02.dev
'안드로이드' 태그의 글 목록 (2 Page)