목록android (8)
안드로이드 개발일기
📙 remember와 rememberSavable둘 다 composable에서 값을 메모리에 기억하도록 해주는 compose 함수composable 내부에서 변수를 선언하면, recomposition 되서 ui가 다시 그려질 때 변수가 날라가기 때문에 데이터 저장이 필요함이때 remember를 쓰면 recomposition이 되어도 데이터가 날라가지 않음🧐 rememberSavable?- 화면 회전, 권한 변경과 같이 액티비티가 재시작하는 경우에도 값을 유지해야 한다면 사용- 내부적으로 Bundle에 저장할 수 있는 값만 지원해서, primitive type, Parcelable, Serializable 만 저장 가능- 만약 복잡한 객체를 저장해야 한다면 Saver 를 만들어야 함👩💻 어떻게 r..

AppCheckFirebase의 Storage, Realtime DB 등 api에 접근해야 하는 상황에서승인되지 않은 클라이언트가 액세스하는 것을 방지하여 api 리소스를 보호합니다. 안드로이드에서는 PlayIntegrity, SafetyNet을 이용해 앱 체크를 적용할 수 있습니다. SafetyNet은 deprecated 되었기 때문에, 여기서는 PlayIntegrity 사용을 설명하겠습니다. Play Integrityplay integrity api는 사용자가 정품 android 기기에서, Google Play 등 정상적인 루트로 플레이 스토어의 서명이 된 정상적인 앱을 설치하여 실행한 것인지 확인합니다. 이 과정을 위해 플레이 콘솔에서 firebase 프로젝트 연결, firebase 콘솔에서 앱 등..
구현하고자 하는 기능 앱이 백그라운드에서 task를 수행하고, 완료되면 이벤트를 받아서 추후 로직을 수행한다.-> 앱이 종료되어도 재실행시 계속 수행해야 하므로 WorkManager를 사용-> 이벤트 수신을 위해 WorkManager.getWorkInfoByIdFlow를 사용 로직1. UseCase에서 WorkRequest를 만들고 WorkManager.enqeue에 넣는다.2. WorkManager의 일이 끝나면 이벤트를 받기 위해 Flow를 사용한다.3. 호출한 UseCase의 메소드는 WorkManager의 수행 완료 값을 가지고 Flow 형태로 반환한다.4. viewModel은 이를 consume하여 추후 로직을 수행한다. 코드UseCasesuspend fun doTask(): Flow { ...
1. 파일 선택기로 pdf 파일 가져오기 앱은 사용자에게 GET_CONTENT로 파일을 로드하고 pdf를 가져오도록 기능을 제공해야 합니다. 아래는 ManagedActivityResultLauncher를 사용하여 액션을 수행하고 결과 값으로 pdf를 가지고 반환하는 코드입니다. val openDocumentLauncher: ManagedActivityResultLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult? -> val uri = result?.data?.data Log.i(TAG, "pdf uri $uri") } ..

UseCase는 domain 영역으로, 유저가 요청하는 동작을 수행하여 유저가 해당 서비스를 통해 하고자 하는 것을 의미합니다. 주로 UseCase에는 ViewModel이 Repository의 메소드를 호출하는 코드가 들어가며, 로직을 캡슐화 합니다. 저는 BaseUseCase를 두고, 이를 상속하여 UseCase 클래스를 구현합니다. abstract class BaseUseCase() { suspend operator fun invoke(params: P): ResultData { return try { execute(params) } catch (e: Exception) { ResultData.Error(errorMessage = e.toString()) } } protected abstract s..
날씨 앱을 만들면서 3개의 API를 호출하고 모두 완료되었을 때 화면을 업데이트하는 로직이 필요했습니다. MVVM과 LiveData를 사용하는 프로젝트에서는 MediatorLiveData를 이용하여 위 문제를 해결하곤 했습니다. 하지만 현재 구현하고 있는 날씨 앱 프로젝트는 Jetpack Compose와 MVI 패턴을 따르고 있는데, LiveData 사용을 최소화하는 것을 목표로 두고 있어 Flow를 사용할 수 있는 방법을 고심했습니다. 저의 코드는 각 API를 호출하면 Flow형태로 리턴하는데, flow를 결합하는 combine을 사용하여 모든 API가 완료되었을 때 로직을 실행하도록 구현하였습니다. private fun requestMultipleApi(location: LatAndLong) { vi..

class MarketDiffUtil( private val oldList: List, private val newList: List ) : DiffUtil.Callback() data class Person( var name: String, var age: Int ) class PersonAdapter: RecyclerView.Adapter() { ... private var personList: List? = null fun submitList(list: List?) { val diffUtil = DiffUtil.calculateDiff( MarketDiffUtil( oldList = this.personList ?: emptyList(), newList = list ?: emptyList() ) )..

앱에서 web을 로드하는 방법은 두 가지가 있습니다. 하나(좌측)는 브라우저(Chrome 등 디바이스에 설치되어 있는 브라우저 앱을 이용하여 url을 로드)하는 방식, 다른 하나는(우측) 현재 실행하고 있는 앱에서 url을 로드하는 방식입니다. 단순히 브라우저를 로드하는 방식이라면 좌측으로 진행하는 것을 권장하고 있습니다. 하지만 이 방법은 브라우저를 좀 더 세밀하게 제어할 수 없기 때문에 web간의 통신이나 UI 등 세부 작업이 필요하다면 우측 방법을 사용합니다. 여기서 잠깐, web을 띄우기 전에 앱에서 필요한 몇 가지 세팅이 있습니다. 가장 첫 번째는 권한을 부여하는 것입니다. ... 인터넷 사용에 대한 권한을 사용자에게 요청하는 이유는 아래와 같습니다. 1. 보안상의 이유 2. 데이터 사용이 필요..