프로그래밍/Android 134

[안드로이드] Airbnb Epoxy 라이브러리 놓치기 쉬운 부분들

개발중인 앱에서 RecyclerView는 Epoxy를 사용하고 있는데 상당히 편리함을 누렸지만 제대로 알지못하고 있는거 같아서 공식문서를 쭉 훑어보았다. 이번 글에서는 공식 문서와 소개 페이지에서 설명하고 있는 요소들 중에서 놓치기 쉬웠던 부분들 몇가지를 체크하려한다. EpoxyAttribute EpoxyAttribute를 사용하면 자동 Diffing에 사용되는 hashCode()나 equals() 같은 메소드가 생성되는데, 이를 원하지 않는다면 @EpoxyAttribute(hash=false) 로 꺼둘 수 있다. 클릭 리스너처럼 매번 bind 될때마다 재생성되는 필드들에 적용하면 좋다. Hiding Models View가 조건부로 보여지고 숨겨져야할때 사용할 수 있다. model.show(boolean..

Upstream Flow, Downstream Flow

Upstream Flow Producer Block에서 생성한 Flow , 현재 연산자 전. Flow를 설명할때 대부분은 UI를 가장 아래쪽에, Remote data source를 가장 위쪽에 위치하는 도식으로 표현되는데, 상류의 물(데이터)이 아래쪽으로 내려오는식으로 이해하면된다. Downstream Flow 현재 연산자 이후의 모든 Flow collect 새로운 값이 생길때마다 호출되는 함수를 매개변수로 받는다. collect를 호출할 때마다 새 Flow가 생성된다. 이러한 Flow는 Cold Flow라고 하는데, 필요에따라 생성되고, 관찰되는 중에만 데이터를 전송하기 때문이다. StateFlow 컬렉터가 없더라도 데이터를 보관하고 있다. 출처 Android Dev Submmit 2021 - Kotl..

LiveData를 버리고 StateFlow를 써야할까요?

Flow 비동기식으로 계산할 수 있는 데이터 스트림. Flow는 값 시퀀스를 생성하는 Iterator와 매우 비슷하지만 정지함수를 사용하여 값을 비동기적으로 생성하고 사용한다. Python의 generator와 비슷하게 이해하면 될 듯. 생산자: 스트림에 추가되는 데이터를 생산. 코루틴 덕분에 비동기적으로 생산도 가능. (Remote Datasource) 중개자(*optional): 스트림에 내보내는 각각의 값이나 스트림 자체를 수정할 수 있다. 소비자: 스트림의 값을 사용한다. 생산자는 저장소, 소비자는 UI 인터페이스라고 받아들일 수 있다. 하지만 UI 레이어가 사용자 입력이벤트의 생산자 역시 될 수 있다. StateFlow의 특징 항상 값을 가지고 있다. 단 하나의 값만을 가진다. 여러 옵저버를 가..

안드로이드 Unity 플러그인 만들기

회사에서 GoogleAnalaytics나 AppsFlyer처럼 게임 중 발생하는 이벤트들을 캐치해서 보내는 SDK를 개발할 일이 생겼는데, Native를 왠만하면 이용하지 않는 편으로 구현하려했으나 최종 코드 가독성이라던가 파일 관리, 추상화 등의 이유로 Native를 사용하기로 했다. 오늘은 그때를 돌아보며 귀찮지만...처음 연결했던 방법을 적어보려한다. 1. classes.jar 추출하기 이번이 나의 처음 SDK 개발이었으며, Unity조차도 잘 몰랐다. 처음엔 Unity와 Android가 어떻게 소통한다는거지? 부터 이해가 필요했다. 둘 사이의 소통을 위해, Unity 라이브러리가 존재한다. 일반적으로는 아래 경로들에 위치하며, 이름은 classes.jar다. 이 파일을 복사하여 어딘가에 저장해두자..

kotlin dsl 적용중 versionNeededToExtract 오류 해결방법

java.lang.IllegalArgumentException: Unexpected versionNeededToExtract (0) at androidx/viewbinding/R.class at org.jetbrains.kotlin.cli.jvm.compiler.jarfs.ZipImplementationKt.parseCentralDirectory(ZipImplementation.kt:110) at org.jetbrains.kotlin.cli.jvm.compiler.jarfs.FastJarHandler.(FastJarHandler.kt:25) at org.jetbrains.kotlin.cli.jvm.compiler.jarfs.FastJarFileSystem$myHandlers$1.fun(FastJarFil..

[Android Studio] 범블비 Network Inspector 인코딩 깨짐 해결방법

안드로이드 스튜디오 범블비(Bumblebee) 버전으로 업데이트하니 원래 잘 나오던 Network Inspector에서의 응답 글자 인코딩이 깨져보였다. 해결방법 해결방법은 Retrofit Request Header에 Accept-Encoding을 추가해주면된다. Accept-Encoding: identity; 이는 클라이언트가 지원하는 인코딩을 서버에 알려주는 것인데, identity의 경우 압축이나 수정없이 어떠한 인코딩도 수행되지 않음을 의미한다. 실제 프로덕션에서는 gzip 인코딩등 압축을 이용할 수 있기때문에 Debug 모드일때만 Accept-Encoding을 identity;로 바꿔주도록 조건문을 추가하는 것이 좋다. 1. 개별 API에 추가하는 방법 @Headers("Accept-Encodi..

[Android] 안드로이드로 게임을 만들어 보았다

그것이 유저를 위해서라면... 게임 멤버십 서비스 플레이오는 모바일 게임을 플레이 하고, 게임 플레이에 대한 보상을 받을 수 있는 앱이다. 앱 특성상 사용 연령대는 어린편이나 게임 시간 측정을 위해 안드로이드에서 오버레이 권한과 앱 사용시간 접근을 허용하는 등 처음 사용법이 다소 어려운 편이다. 그래서 유저 튜토리얼을 추가하여 훈련시켜보는 건 어떨까하는 생각에 ... 앱에서 튜토리얼을 위한 모의 게임을 만들자! 라고 제안했는데 받아들여졌고 결국 그렇게... 허접하지만 미니 게임을 만들게되었다. 이 글에서는 이번에 안드로이드에서 미니 게임을 만들면서 고려했던 문제들을 하나 하나씩 살펴보려한다. # 어떤 게임? 위 짤이 바로 만든 게임의 화면이다. 노란 새 버디가 유치원에 등교를 하는데, 버디의 부모님인 동..

[안드로이드] BottomSheetBehavior로 차이 카드 앱 처럼 UI 구성하기

어? 이거 좋다! 차이카드에는 올려서 부스트하기 기능이있다. 아래에서부터 핸들을 쭉 땅겨서 부스트가 작동하도록하는 것인데... 플레이오에서 레벨업 페이지와 내역페이지가 리스트로 죽 늘어진 레이아웃을 보고...차이처럼 구성해보는 것은 어떨까 건의드렸다. 성능상의 문제가 있기도 했지만, 작은 폰을 쓰는 유저들은 아래에 내역이 있는지 조차 모를 확률도 있었다. (ㅋㅋㅋ) 호기롭게 건의했지만 혼자서 공부하다보니 저런 레이아웃이 어떻게 구현되어있고, 뭐라고 검색해야 할지도 몰랐는데 해답은~ BottomSheet이었다. 그동안 BottomSheet은 BottomSheetDialog로만 이용해봐서 일반 뷰에서 쓰는건 처음이었는데, behavior만 설정해주면 간단히 멋진 레이아웃을 구현할 수 있었다. 다음 화면과 같..

adb에서 쉽게 딥링크(Deeplink) 열기 / 인텐트(Intent) 전송

딥링크 열기 adb shell am start -d "rally://accounts/Checking" -a android.intent.action.VIEW Action을 가진 액티비티 실행 -a 옵션 뒤의 액션을 가지고 있는 액티비티가 실행된다. adb shell am start -a android.intent.action.MAIN 패키지를 지정한 실행 -p 옵션 뒤에 패키지를 설정하면 해당 패키지에서 실행된다. adb shell am start -a android.intent.action.MAIN -p com.example.app 액티비티 실행 -n 옵션 뒤에 컴포넌트 이름을 적어준다. adb shell am start -a android.intent.action.MAIN -n com.example.a..

[안드로이드] VideoView 소리없이 비디오 재생하기

사용자의 폰에서 돌아가는 다른 미디어 플레이에 지장을 주지 않으면서 현재 비디오 뷰의 Volume을 줄여서 재생해야하는 경우가 있다. MediaPlayer.setVolume(0F, 0F)를 하게되면 볼륨은 줄여지지만, 동시에 미디어 볼륨에도 지장을 주므로 VideoView 내에서 AudioFocus를 AUDIOFOCUS_NONE으로 설정해주는 작업이 필요하다. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // MusicPlayer를 방해하지 않음 setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE) }