안드로이드 공부한 내용들을 바탕으로 질문을 만들어 정리하는 내용!
🔍 인텐트란 무엇인가요?
안드로이드를 구성하는 컴포넌트들을 실행하거나 컴포넌트들 사이에서 데이터를 주고받는 메시징 객체의 역할을 하는 것입니다.
🔍 명시적 인텐트와 암시적 인텐트의 차이는 무엇인가요?
명시적 인텐트는 같은 앱내에서의 컴포넌트들 사이에 실행 및 데이터를 주고받도록 하는 역할을 하며 컴포넌트 클래스의 이름을 직접적으로 명시합니다.
암시적 인텐트는 이와 달리 타 앱의 컴포넌트의 실행 및 데이터를 전달하도록 하며 action, type, data를 intent 객체에 지정해주어야 합니다.
🔍 앱이 빌드되기 까지의 과정이 무엇인가요?
1. 코드 분석 및 검사 (Lint Check)
-> Lint 도구로 분석해 코드에서 발생하는 잠재적 문제나 비효율적인 코드를 탐지
2. Gradle 빌드 시스템 초기화
-> Gradle은 안드로이드 프로젝트의 빌드 도구로, 각종 의존성과 플러그인 설정을 관리한다.
-> Gradle 캐시를 이용해 이미 빌드된 모듈은 재사용한다.
3. 코드 컴파일
-> Kotlin 및 Java 코드가 JVM 바이트 코드로 변환됨.
-> 코틀린 코드 사용시, Kotlin 컴파일러가 동작하며 코드를 컴파일한다.
-> res/ 폴더에 있는 XML 리소스가 binary format으로 변환된다.
-> R.java 파일이 생성되어 XML 리소스들을 참조할 수 있게 된다.
4. 데이터 바인딩 및 코드 생성
-> 바인딩 클래스 자동 생성 됨.
-> Room, Dagger 같은 라이브러리가 코드 생성 도구를 통해 추가적인 코드를 생성할 수 있다.
5. DEX 파일 생성(Dalvik Executable)
-> JVM 바이트 코드를 안드로이드에서 실행 가능한 DEX 파일로 변환한다.
-> 멀티-DEX가 필요한 경우 여러 개의 DEX 파일이 생성될 수 있다. (이 과정에서 성능을 최적화함)
6. APK(또는 AAB) 패키지 생성
-> 컴파일된 코드, 리소스, 매니페스트 파일을 하나의 APK 또는 AAB 파일로 패키징함.
-> ProGuard/R8를 사용하면 코드가 최적화되고 난독화된다.
7. 서명
-> 앱이 실행되기 전에 디버그 키 또는 릴리즈 키로 서명함.
-> 디버그 모드로 빌드할 떄는 안드로이드 스튜디오가 자동으로 제공하는 디버그 키를 사용한다.
8. APK 정렬 및 최적화
-> Zipalign 도구를 통해 APK 파일의 리소스를 최적화해 메모리 사용을 개선함.
9. 에뮬레이터 또는 디바이스 연결 및 설치 및 실행
-> ADB가 사용되어 디바이스와 통신하며 앱을 설치함.
🔍 안드로이드 OS의 주요 계층은 무엇인가요?
1. 리눅스 커널
-> 하드웨어와의 인터페이스 역할을 한다.
-> 메모리 관리, 프로세스 관리, 네트워크 스택 등을 담당한다.
-> 드라이버를 통해 카메라, Bluetooth, Wi-Fi, 오디오와 같은 하드웨어를 제어한다.
2. Hardware Abstraction Layer(HAL)
-> 하드웨어와 상위 계층이 독립적으로 동작하게 한다.
-> HAL 모듈은 특정 하드웨어 기능을 제공하며, OS가 하드웨어와 소통할 수 있게 도와준다.
3. Native Library & Android Runtime (ART)
-> 네이티브 라이브러리 : OpenGL(그래픽), SQLite(데이터베이스), WebKit(브라우저) 등 시스템 기능에 필요한 기본 라이브러리들이 포함됩니다.
-> Android Runtime : ANdroid의 애플리케이션 런타임 환경을 제공하며, 가비지 컬렉션과 JIT 컴파일을 통해 성능 최적화를 한다.
4. Application Framework(애플리케이션 프레임워크 계층)
-> 앱 개발자에게 제공되는 API와 컴포넌트 집합
-> Activity Manager : 애플리케이션의 생명주기 관리
-> Content Providers : 데이터 공유 관리
-> Resource Manager : 외부 리소스 관리
-> Location Manager : 위치 서비스 관리
-> Notification Manager : 앱에서 푸시 알림을 관리
5. Applications
-> 사용자가 상호작용하는 UI가 제공된다.
🔍 ART와 Dalvik의 차이점은 무엇인가요?
Dalvik
-> JIT 컴파일 사용 : 코드 실행 중에 필요한 부분만 즉시 컴파일한다.
-> 런타임 시 컴파일이 이루어지기 때문에 성능이 다소 느리고 배터리 소모가 크다.
ART
-> AOT(Ahead-of-Time) 컴파일 사용 : 앱 설치 시 코드 전체를 미리 컴파일한다.
-> 앱 실행 속도가 더 빠르고, 메모리 관리가 효율적이다.
-> 앱 설치 시 더 많은 시간이 소비되고, 설치 파일 크기가 커질 수 있다.
🔍 Activity의 생명주기는 무엇인가요?
onCreate()
-> 처음 생성될 때 호출되며, 초기화 작업을 수행한다.
onStart()
-> 화면에 나타나기 시작할 때 호출된다.
onResume()
-> 포그라운드에 있을 때 호출되며, 사용자와 상호작용이 가능
-> UI 업데이트 및 센서나 위치 서비스와 같은 자원을 연결
onPause()
-> Activity가 다른 화면으로 전환되거나 일시 중지될 때 호출된다.
-> 데이터 저장, 애니메이션 정지를 처리하고 중요한 상태를 저장한다.
onStop()
-> 완전히 사라질 때 호출
-> CPU나 배터리를 소모하는 백그라운드 작업을 중지
-> 데이터를 디스크에 저장하거나 네트워크 연결을 해제할 수 있다.
onRestart()
-> 다시 시작될 때 호출
-> onStop()가 onStart() 사이의 과도기적 단계
onDestroy()
-> 완전히 종료될 때 호출됨.
-> 메모리 해제, 데이터베이스 연결 해제 등 마무리 작업을 처리
-> 시스템이 메모리를 회수할 때도 호출됨.
🔍 Activity 생명주기 간 흐름
1) Activity 시작
onCreate() -> onStart() -> onResume()
2) 다른 Activity로 전환
onPause() -> onStop()
3) Activity 복귀
onRestart() -> onStart() -> onResume()
4) Activity 종료
onPause() -> onStop() -> onDestroy()
🔍 Fragment 생명주기
onAttach
-> Fragment가 Activity에 연결될 때 호출
onCreate()
-> Fragment가 초기화될 때 호출
onCreateView()
-> Fragment의 UI를 생성하는 단계
onViewCreated()
-> 뷰가 생성된 후 호출됨
onStart()
-> Fragment가 화면에 나타나기 직전 호출됨.
onResume()
-> 상호작용이 가능할 때 호출
onPause()
-> 일시 중지될 때 호출
onStop()
-> 더 이상 화면에 보이지 않을 때
onDestroyView()
-> 뷰가 파괴될 때 호출
onDestroy()
-> Fragment가 완전히 파괴될 때 호출
onDetach()
-> Fragment가 Activity에서 분리될 때 호출
🔍 안드로이드 Service란 무엇인가요?
서비스는 UI 없이 백그라운드에서 작업을 실행하는 Android 컴포넌트입니다.
장시간 실행해야 하는 작업(음악 재생, 파일 다운로드)나, 사용자와 직접 상호작용하지 않는 작업에 사용된다.
액티비티가 종료되더라도 서비스는 계속 실행됩니다.
서비스는 백그라운드에서 동작하며, 멀티태스킹 환경에서 앱이 유용하게 기능할 수 있도록 도와줍니다.
🔍 서비스의 종류에는 무엇이 있나요?
1. 포그라운드 서비스
-> 알림을 통해 사용자에게 실행 중임을 알립니다.
-> 시스템에 의해 높은 우선 순위를 가지며, 메모리가 부족할 때도 쉽게 종료되지 않는다.
-> 음악 플레이어, GPS 추적 앱 등이 사용됩니다.
2. 백그라운드 서비스
-> 사용자에게 알림을 표시하지 않는다.
-> 시스템이 리소스를 관리할 때 우선 순위가 낮아져 쉽게 종료될 수 있다.
-> 사용자와 직접 상호작용하지 않고 백그라운드에서 실행됩니다.
-> Android 8.0(Oreo) 부터 백그라운드 작업에 제한이 생겨 WorkManager나 Foreground Service로 대체되는 경우가 많습니다.
3. 바운드 서비스
-> 다른 컴포넌트(Activity, Fragment)가 서비스에 바인딩하여 통신할 수 있습니다.
-> 클라이언트 - 서버 모델로 사용하며, 서비스는 특정 클라이언트가 있을 때만 실행됩니다.
🔍 서비스의 생명주기는 무엇인가요?
onCreate()
-> 서비스가 처음 생성될 때 한번 호출됩니다.
-> 초기화 작업을 수행한다.
onStartCommand()
-> 서비스가 시작될 때 호출된다.
-> 서비스가 명령을 받고 실행을 시작한다.
-> 반환값으로
START_STICKY (서비스가 비정상 종료되면 자동 재시작)
START_NOT_STICKY(비정상 종료 후 재시작하지 않음)
START_REDELIVER_INTENT(종료된 서비스가 다시 시작되며, 이전 Intent를 전달)
onBind()
-> 다른 컴포넌트가 서비스에 바인딩 할 때 호출됩니다.
-> 바운드 서비스에서만 사용한다.
onUnbind()
-> 클라이언트가 서비스와 바인딩 해제할 때 호출된다.
onDestroy()
-> 서비스가 종료될 때 호출된다.
-> 메모리 정리 작업 등 종료 시 필요한 작업을 수행한다.
🔍 바인드 서비스에서 클라이언트와 통신하는 방법은 무엇인가요?
바인드 서비스에서는 Binder 클래스를 사용해 클라이언트와 통신할 수 있다. 서비스는 onBind() 메서드에서 Binder를 반환하고, 클라이언트는 이를 통해 서비스의 공개 메서드에 접근할 수 있다.
예를 들면, 서비스에서 데이터를 제공하거나 작업을 수행하는 메서드를 호출할 수 있다.
🔍 ViewModel이란 무엇인가요?
ViewModel은 안드로이드에서 UI 관련 데이터를 관리하기 위해 설계된 클래스입니다. 데이터가 ViewModel에 저장되면 구성 변경이 발생하더라도 데이터를 유지할 수 있습니다.
🔍 ViewModel의 생명주기는 어떻게 동작하나요?
ViewModel은 Activity 및 Fragment보다 생명주기가 길기 때문에 UI 컴포넌트들이 파괴되더라도 데이터가 남아있습니다. 그래서 구성 변경이 되어도 데이터를 유지할 수 있는 것입니다.
🔍 ViewModel의 인스턴스를 얻는 방법은 무엇인가요?
ViewModelProvider를 사용해 ViewModel의 인스턴스를 가져옵니다.
🔍 Coroutine을 사용하는 이유와 주요 이점은 무엇인가요?
비동기 작업을 효율적으로 처리하기 위해 사용합니다. 경량 쓰레드로 동작하며, 실제로 쓰레드를 생성하지 않으면서 쓰레드처럼 비동기 작업을 수행할 수 있습니다. 이로 인해 멀티 쓰레드를 직접 사용하는 것보다 리소스 오버헤드가 적고, 관리가 간단합니다.
🔍 Compose를 사용할 때 기존 XML 기반 UI와 비교해서 얻을 수 있는 이점은 무엇인가요?
Compose는 재사용에 용이한 컴포저블 함수를 지원해, 특정 도메인이나 요구사항에 맞게 컴포넌트를 모듈화하고 쉽게 재사용할 수 있습니다. XML로 재사용하고자 한다면, 별도의 파일을 생성해야 했던 번거로움을 줄일 수 있습니다.
또한, Compose는 상태 기반의 선언적 UI를 지원해, UI를 상태에 따라 자동으로 업데이트 할 수 있어, View를 수동으로 업데이트하던 XML 방식보다 효율적입니다.
마지막으로, XML에는 UI를 Activity/Fragment에 기능적인 부분을 따로 적어줘야 하지만, 컴포즈는 Kotlin 코드로 UI를 작성해 하나의 파일에서 UI와 로직을 작성할 수 있고, 관리도 용이합니다.
🔍 안드로이드에서 Hilt를 사용하는 이유와 그 장점에 대해 설명해 주세요.
안드로이드에서 Hilt는 의존성 주입을 간단하고 효율적으로 구현하기 위해 사용합니다. 이점으로는 컴파일 타임에 의존성 주입을 검증하기 때문에 런타임 에러를 줄이고, 안정적인 코드를 작성할 수 있습니다.
또한 안드로이드의 생명 주기와 긴밀이 통합되어, Activity, Fragment, ViewModel 등 다양한 컴포넌트에서 의존성을 쉽게 주입할 수 있습니다.
마짐가으로, 개발자가 의존성의 수명 주기를 쉽게 관리할 수 있도로 @Singleton, @ActivityRetainedScoped와 같은 스코프 어노테이션을 제공합니다.
🔍 WorkManager 사용 이유와 특징?
API 26 이상에서 백그라운드 서비스 제한에 대응하기 위해 도입된 솔루션으로, 시스템이 종료되거나 앱이 강제 종료되더라도 작업이 보장되며, 네트워크 상태, 충전 여부 등 다양한 조건에 따라 작업을 예약하고 실행할 수 있습니다. 단발성 작업, 주기적 작업 등 다양한 작업 유형을 지원해, 코루틴을 통합해 비동기 작업을 간편하게 처리할 수 있어 대규모 데이터 동기화, 파일 업로드, 알림 예약 등 안정적인 백그라운드 작업에 적합합니다.
🔍 안드로이드에서 Flow와 LiveData의 차이점은 무엇인가요?
Flow와 LiveData의 가장 큰 차이점은 Flow는 Cold Stream이고, LiveData는 Hot Stream이라는 점입니다.
Flow는 관찰자가 구독을 시작해야 데이터가 전달되지만, LiveData는 관찰자가 없어도 데이터가 변경되면 값을 유지할 수 있습니다.
🔍 Jetpack Compose에서 remember, rememberSaveable, mutableStateOf의 차이점
Jetpack Compose에서 remember, rememberSaveable, mutableStateOf의 차이점은 상태 유지 방식에 있습니다.
먼저, mutableStateOf는 Compose에서 상태를 저장하는 객체로, UI가 해당 상태를 관찰하고 값이 변경되면 자동으로 리컴포즈(재구성)됩니다. 하지만, mutableStateOf만 사용하면 UI가 재구성될 때 값이 초기화되는 문제가 발생합니다.
이를 해결하기 위해 remember를 사용하면, Composable이 재구성될 때 기존 값을 유지할 수 있습니다. 하지만 remember는 화면 회전이나 프로세스 종료 시에는 값이 유지되지 않는다는 단점이 있습니다.
반면, rememberSaveable은 remember와 유사하지만, Bundle을 활용해 데이터를 저장하기 때문에 화면 회전(프로세스 종료) 후에도 상태를 유지할 수 있습니다. 따라서, 사용자의 입력 값이나 중요한 UI 상태를 유지해야 하는 경우 rememberSaveable을 사용하는 것이 적절합니다.
결론적으로, 단순한 상태 저장에는 mutableStateOf를 사용하고, UI 재구성 후에도 상태를 유지하려면 remember를, 화면 회전 후에도 상태를 유지하려면 rememberSaveable을 선택해야 합니다.
'정리' 카테고리의 다른 글
[정리] 안드로이드 - Compose (0) | 2024.11.09 |
---|---|
[정리] 네트워크 정리 (0) | 2024.08.29 |
[정리] 프로그래밍 언어 정리 (0) | 2024.05.29 |
[정리] 자료구조 정리 (0) | 2024.05.28 |
[정리] 운영체제 정리 (0) | 2024.05.27 |