프로그래밍/Android 131

[안드로이드] 특정 시간 내 중복 Request를 막는 OkHTTP Interceptor 구현하기

특정시간 안에 보낸 동일한 Request에 대해서 서버에 요청하지 않고, 이전에 받은 응답값을 그대로 내려주는 Interceptor를 구현해보았다. Response Body를 어떻게 재사용할 것인가 고민을 많이 했는데, ByteArray 형태로 읽어두고 중복된 요청일때 ResponseBody로 만들어주는 방법을 사용해보았다. 이렇게 짧은 시간안에 연속적으로 요청을하더라도, 500ms 이후에만 새로 요청을 하게된다. 개발중인 앱의 Request Method가 전부 POST이기때문에, Request body까지 읽어서 hashing을 하고있는데, 그럴 필요까지 없으신분들은 Request URL 자체를 hash 값으로 잡아도 무방할 것이다. 혹시 유용했다면 Star를~! HTML 삽입 미리보기할 수 없는 소스

[안드로이드] Push할 때마다 Auto-Formatting적용하기 : GitHook으로 코딩 스타일 맞추기

작업환경을 타지 않는 방법의 필요성 코딩 스타일의 일관성은 가독성, 협업에서 중요한 포인트이지만 개인적인 코딩 습관들, 빡빡한 일정들 등으로 인해 지키기 쉽지 않다. IDE에서 저장시에 코드 포맷팅을 해주는 기능들이 있기는 하지만, 작업환경마다 세팅해줘야한다는 단점이 있다. 따라서 어떤 환경에서 작업하더라도 코딩 스타일을 지켜줄 수 있는 방법이 필요했다. (이 원문을 응용하여 작성된 글입니다.) GitHook + ktlint 그것은 바로 GitHook을 이용하는 방법이다. git init을 하면 .git/hook 폴더에는 여러 GitHook 샘플들이 생긴다. 이 경로 안에 내가 Hook을 발생시키기 원하는 시점에 대한 파일을 “확장자 없이” 넣어주면 간단히 Hook 세팅을 할 수 있다. 샘플 파일들은 ...

[안드로이드] ExoPlayer 깜빡거리거나 검은 화면(Black screen)이 뜰 때

문제발생 Epoxy로 무한 반복되는 배너 캐러셀에 동영상을 적용시키는 중에, 간혹 동영상이 재생될때 검은 화면만뜨고 재생이 안되거나 깜빡이는 문제가 있었다. *하나의 ExoPlayer를 RecyclerView.Adapter에서 재활용해가면서 쓰는 사례다. 정신차리고 setPlayer() Document를 자세히 읽어보니... Player를 다른 View에 붙일때 switchTargetView()를 쓰는걸 추천한다고 되어있다. 하지만 setPlayer()를 직접 쓰고자 할 경우 이전 View에서 Player를 분리하기 위해 setPlayer(null)을 호출하기 이전에 새로운 View에 Player를 연결시켜야 한다. *switchTargetView를 직접 써보려고 했으나, 지원하지 않는 메소드였다. 해결..

[안드로이드] java.lang.IllegalStateException: An instance of OnFlingListener already set 해결

문제 발생 @ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT) internal class PagerSnapHelperCarousel @JvmOverloads constructor( context: Context ) : Carousel(context) { init { if (onFlingListener == null) { PagerSnapHelper().attachToRecyclerView(this) } } } Epoxy의 Custom Carousel로 SnapHelper를 붙이는 도중 OnFlingListener가 이미 등록되어있다는 오류가 발생했다. 당연하게도 이유는 RecyclerVIew에 OnFlingListener가 이미 등록되어 있어..

[CI/CD] Firebase Test Labs UI Test 자동화하기

CI/CD Tool로 Bitrise (CLI)를 사용하고 있는데, Workflow에 UI Test 단계를 추가해보려고한다. gn_test Workflow를 살펴보면, git pull 로 프로젝트를 땡겨오고, 이전에 만든 test용 apk를 제거한다. UI Test용 빌드를 생성하고, Firebase Test Lab으로 기기에 테스트 한다. gn_test: steps: - script@1: inputs: - content: "bash $ROOT/scripts/gitpull.sh" - script@1: inputs: - content: "bash $ROOT/scripts/delete_test_apk.sh" - android-build-for-ui-testing@0: inputs: - project_locat..

Android Studio 이전 릴리즈 다운받는 방법

오늘 Dolphin으로 업데이트 했다가 완전 버그로 고생했다. ㅠㅠ 다운그레이드 해보려고 했는데 구글에서 제공하는 Android Studio 다운로드 자료실에는 버전이 몇 개 없었다. https://developer.android.com/studio/archive?hl=ko 1. 버전정보 복사하기 아래 JetBrain 사이트에서 확인하면 모~~~든 Release 리스트가 나온다. 여기에서 다운로드 할 버전 번호를 복사해둔다. https://plugins.jetbrains.com/docs/intellij/android-studio-releases-list.html#2021 예를들면 Chipmunk Patch 2를 다운받고 싶다면 "2021.2.1.16"을 복사한다. 2. 자료실에서 다운로드 링크 복사 자료..

[안드로이드] 예제로 보는 NavigationComponent

Navigation Component란? 기존의 안드로이드에서는 여러 단계의 Fragment 진행을 추적하고, 다루기 어려웠다. Jetpack의 Naviagtion Component는 이러한 문제를 개선하기 위해서 등장했는데, iOS의 스토리보드처럼 여러 화면 이동을 그래프(Graph)로 시각화하여 보여주고 NavController를 이용해 한 곳에서 전환을 관리할 수 있도록 도와준다. “오~좋은건 알겠는데, 다음 프로젝트에 써야지^^”라는 생각이 스친다! 당장 레거시 코드에서 어떻게 활용하면 좋을지 막막할 것이다. (내가 그랬기때문) 그래서 회원가입을 예로 들어서, 현재 진행중인 프로젝트에 Navigation Component를 사용하는 방법을 포스팅해보겠다. # 간단한 개념 3가지 NavGraph: ..

[안드로이드] HiltWorker 오류 Could not create Worker 해결방법

HiltWorker로 Worker에 의존성 주입받기 우선 필요한 dependency는 다음과 같다. Coroutine은 예시에서 CoroutineWorker를 만들 것이기때문에 넣어주었다. implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1' implementation "com.google.dagger:hilt-android:2.38.1" kapt "com.google.dagger:hilt-android-compiler:2.38.1" implementation("androidx.hilt:hilt-work:1...

[안드로이드] WorkManager Worker 디버깅하기

AndroidStudio의 App Inspector > Background Task Inspector에서 현재 돌아가고있는 Background Task 목록과 상태를 확인할 수 있다. 하지만 사진처럼 Status가 Failed가 떴을때는 정확한 원인을 진단하기가 힘든데, 이때 Worker에 생긴일을 디버깅하는 방법을 소개한다. adb logcat | grep -e "WM-WorkerWrapper" 터미널에서 위 명령어를 사용하면 WorkerManager 관련 로그들이 필터링된다. adb가 낯설다면 이 포스트(adb 개념과 사용방법)를 참조하면된다. 아니면 AndroidStudio내 logcat에서 로그 수준을 Info로 낮추고 찾아도된다! 09-13 16:54:01.737 14800 14838 I WM-..

[안드로이드] View를 터치 입력에 따라 회전하기 (핸들 구현)

이번에 만들어볼 것은 사용자의 터치 입력에따라 회전하는 핸들뷰다. 다양하게 활용할 수 있는데, 회사에서 뽑기 기계를 만들어보자는 아이디어에서 삼각함수로 뽀리면 되겠는데?! 라는 생각에서 만들어서 검증해보았다. xml은 터치 입력을 받을 view_touch와 ImageView인 handle 단 두개로 이루어져있다. center에는 touch view의 가운데 지점을 저장하고, handle 이미지 뷰를 정 중앙으로 옮긴다. val viewTouch = findViewById(R.id.view_touch) val handle = findViewById(R.id.handle) val center = PointF() viewTouch.viewTreeObserver.addOnGlobalLayoutListener(o..