계속 ViewModel로부터 시작하여 모르는 단어들을 ChatGPT한테 물어보며 공부합니다.
* 빨간색 형광펜: 찾아서 알게된 단어(개념) (2024-02-24 기준)
* 초록색 형광펜: 주제에서 벗어나 나중에 찾을 단어(개념)
0. ViewModel이 무엇입니까?
ViewModel은 Android 앱에서 UI 관련 데이터를 처리하고 관리하기 위한 구성 요소 중 하나입니다. 주로 MVVM (Model-View-ViewModel) 아키텍처 패턴에서 사용됩니다. ViewModel은 UI 컨트롤러 및 비즈니스 로직과 UI 간의 중간 매개체 역할을 합니다.
1. Lifecycle-aware: ViewModel은 Android의 수명 주기를 인식하고, 이에 따라 데이터를 유지합니다. 활동이 재생성되거나 구성 변경이 발생해도 ViewModel은 유지되므로 데이터 유지 및 UI 상태 관리에 용이합니다.
2. UI와 데이터 분리: ViewModel은 UI 관련 데이터를 처리하고, UI 컨트롤러 (Activity, Fragment 등)에서 데이터에 접근할 수 있도록 합니다. 이를 통해 UI 로직과 비즈니스 로직을 분리하여 코드의 가독성과 유지 보수성을 향상시킵니다.
3. 구성 변경 및 화면 회전 처리: ViewModel은 구성 변경 시에도 데이터를 보존하므로, 화면 회전 또는 다른 구성 변경으로 인한 데이터 손실을 방지합니다.
4. 메모리 누출 방지: ViewModel은 앱의 메모리 누출을 방지하는 데 도움이 됩니다. 예를 들어, 액티비티의 경우 구성 변경으로 인해 onDestroy()가 호출되면, ViewModel은 해당 액티비티의 참조를 계속 유지하지 않습니다.
5. 테스트 용이성: ViewModel은 비즈니스 로직을 분리하고, 단위 테스트를 용이하게 만듭니다. ViewModel의 메서드는 일반적으로 순수한 Kotlin 코드이므로 테스트하기 쉽습니다.
6. 공유 데이터: 여러 UI 컨트롤러가 동일한 데이터에 액세스해야 하는 경우 ViewModel을 사용하여 데이터를 공유할 수 있습니다. 이를 통해 데이터의 일관성을 유지하고 중복을 방지할 수 있습니다.
ViewModel은 Android Jetpack 라이브러리에서 제공되며, androidx.lifecycle.ViewModel 클래스를 상속하여 구현됩니다. ViewModel을 사용하려면 AndroidX 라이브러리를 프로젝트에 추가하고, ViewModelProvider를 사용하여 ViewModel 인스턴스를 얻어야 합니다.
핵심: UI -- ViewModel -- 비즈니스 로직
1. MVVM (Model-View-ViewModel) 아키텍처 패턴이란?
MVVM은 Model-View-ViewModel의 약자로, 안드로이드 앱 개발에서 널리 사용되는 아키텍처 패턴 중 하나입니다. 이 패턴은 UI 로직과 비즈니스 로직을 분리하여 앱의 유지 보수성과 확장성을 향상시키는 데 도움이 됩니다.
-
앱의 데이터 및 비즈니스 로직을 나타냅니다.
-
데이터베이스, 네트워크 호출, 파일 시스템 액세스 등과 같은 데이터 소스와 상호 작용합니다.
-
일반적으로 데이터의 구조를 정의하는 데이터 클래스와 데이터를 가져오고 업데이트하는 메서드를 포함합니다.
-
사용자 인터페이스를 나타냅니다.
-
사용자에게 정보를 표시하고 사용자 입력을 처리합니다.
-
화면 구성 요소인 액티비티, 프래그먼트, XML 레이아웃 등을 포함합니다.
-
View와 Model 사이의 중간 매개체 역할을 합니다.
-
UI 관련 데이터를 관리하고 뷰에 표시되는 데이터를 제공합니다.
-
비즈니스 로직을 처리하고 뷰와 독립적으로 데이터 상태를 관리합니다.
-
뷰와의 직접적인 의존성을 줄이고 테스트 용이성을 향상시킵니다.
-
단일 책임 원칙(Single Responsibility Principle) 준수: 각 구성 요소는 단일 책임을 갖고 있으며, 역할이 명확하게 구분됩니다.
-
데이터 바인딩(Data Binding): View와 ViewModel 사이의 데이터 흐름을 자동화하는 데 사용됩니다. 이를 통해 XML 레이아웃과 ViewModel 간의 바인딩을 처리하고 반복적인 코드 작성을 줄일 수 있습니다.
-
확장성과 유지 보수성 향상: 각 구성 요소가 분리되어 있으므로 코드 수정 및 유지 보수가 쉽습니다.
-
테스트 용이성: 비즈니스 로직은 ViewModel에 집중되어 있으므로 단위 테스트 작성이 용이합니다.
MVVM은 안드로이드 앱 개발에서 널리 사용되며, Android Jetpack 라이브러리에서 지원하는 ViewModel과 LiveData와 함께 사용되면 앱의 아키텍처를 더욱 향상시킬 수 있습니다.
핵심: MVVM = View -- ViewModel -- Model
>> MVVM 패턴이란?
9. 단일책임이란 무엇입니까?
단일 책임(Single Responsibility)은 소프트웨어 개발에서 중요한 원칙 중 하나입니다. 이 원칙은 클래스, 모듈 또는 함수와 같은 소프트웨어 구성 요소가 하나의 기능 또는 역할에만 집중해야 한다는 것을 의미합니다.
구성 요소가 단일 책임을 갖는다는 것은 그것이 하나의 명확한 역할을 수행하고, 변경 사항이 발생할 때 한 가지 이유로만 변경되어야 한다는 것을 의미합니다. 이는 코드의 응집성을 높이고, 유지 보수성을 향상시키며, 코드의 이해와 재사용을 증가시킵니다.
예를 들어, 클래스가 사용자 인증 및 세션 관리와 같은 사용자 관리 기능을 담당하고 있으면, 이 클래스는 단일 책임 원칙을 따르고 있지 않습니다. 대신에, 사용자 인증을 처리하는 별도의 클래스와 세션 관리를 처리하는 별도의 클래스로 분리하여 각 클래스가 단일 책임을 갖도록 해야 합니다.
단일 책임 원칙을 준수하면 코드의 유지 보수성이 향상되고, 변경에 대한 위험이 감소하며, 코드의 의도를 명확하게 이해할 수 있습니다. 따라서 소프트웨어 개발에서 이 원칙을 따르는 것은 좋은 코드를 작성하는 데 중요한 요소입니다.
핵심: 단일책임 = 하나의 기능만 가져라
9.1 세션 관리란?
세션 관리(Session Management)는 웹 애플리케이션에서 사용자의 상태를 추적하고 유지하는 프로세스를 의미합니다. 사용자가 웹 사이트에 접속하고 로그인하면, 서버는 해당 사용자에 대한 세션을 생성하고 유지합니다. 이 세션은 사용자가 웹 사이트를 브라우징하는 동안 사용자의 상태 및 활동을 추적하고 유지하는 데 사용됩니다.
1. 세션 생성 및 파기: 사용자가 로그인하면 세션을 생성하고, 로그아웃하거나 일정 시간이 경과하면 세션을 파기합니다.
2. 세션 식별: 각 세션은 고유한 식별자를 갖고 있어서 서버가 각 사용자를 식별하고 구별할 수 있습니다.
3. 세션 유지: 사용자가 활동을 유지하는 동안 세션은 유지됩니다. 예를 들어, 사용자가 페이지를 이동하거나 요청을 보낼 때마다 세션을 업데이트하고 유지합니다.
4. 보안: 세션 관리는 사용자의 인증 및 권한 부여를 포함하여 보안에 관련된 중요한 역할을 합니다. 세션 관리를 통해 사용자는 자신의 계정에 대한 액세스 권한을 유지하고 보호할 수 있습니다.
세션 관리는 주로 웹 애플리케이션에서 사용되지만, 다른 유형의 애플리케이션에서도 유사한 기능을 수행할 수 있습니다. 세션 관리는 사용자 경험을 향상시키고 보안을 강화하는 데 중요한 역할을 합니다.
핵심: 세션관리 = 사용자 상태 추적, 유지
>> 세션이란?
10. ViewModel 간의 바인딩을 처리한다는 것은 무엇인가?
"ViewModel 간의 바인딩을 처리한다"는 말은 MVVM 아키텍처에서 자주 사용되는 용어입니다. 여기서 "바인딩"이란 뷰(View)와 뷰모델(ViewModel) 간의 데이터 연결을 의미합니다.
MVVM에서 뷰는 사용자 인터페이스(UI)를 나타내며, 뷰모델은 UI와 관련된 데이터를 처리하고 제공합니다. 이 두 요소 간의 효과적인 통신은 앱의 동작을 정의하고 사용자 경험을 결정합니다.
바인딩은 뷰에서 발생하는 사용자 입력이나 상태 변화 등의 이벤트를 감지하고, 그에 따라 뷰모델의 데이터를 업데이트하거나 뷰에 반영하는 과정을 말합니다. 이를 통해 뷰와 뷰모델은 서로 독립적으로 유지되면서도 데이터의 일관성을 유지할 수 있습니다.
예를 들어, 사용자가 앱 화면에서 어떤 버튼을 클릭하면, 해당 이벤트가 뷰에 의해 감지되고 뷰모델에 전달됩니다. 뷰모델은 이 이벤트에 따라 데이터를 업데이트하고, 이 업데이트된 데이터는 다시 뷰로 전달되어 화면에 반영됩니다.
바인딩을 통해 뷰와 뷰모델 간의 효율적인 상호 작용이 이루어지므로, 개발자는 UI와 비즈니스 로직을 분리하고 앱의 유지 보수성과 확장성을 향상시킬 수 있습니다.
핵심: 뷰 -- 데이터 연결(바인딩) -- 뷰모델
11. 단위테스트란 무엇인가?
단위 테스트(Unit Test)는 소프트웨어 개발에서 개별 코드 단위의 기능을 테스트하는 프로세스를 의미합니다. 이러한 테스트는 개별 함수, 메서드, 클래스 또는 모듈과 같은 작은 단위의 코드 조각을 대상으로 합니다. 단위 테스트는 해당 코드가 의도한 대로 작동하는지 확인하고 코드 변경 시에 예상치 못한 부작용이 발생하지 않도록 보장합니다.
단위 테스트가 용이하다는 것은 코드가 테스트하기 쉽고, 테스트 케이스를 작성하기 쉬운 구조로 작성되어 있다는 것을 의미합니다. 코드가 의존성을 적절하게 관리하고, 테스트 가능한 방식으로 작성되어 있으면 단위 테스트 작성이 용이해집니다.
MVVM 아키텍처에서 ViewModel 간의 바인딩을 처리한다는 것은 ViewModel 간의 상호 작용이 바인딩 메커니즘을 통해 이루어진다는 것을 의미합니다. 이는 일반적으로 LiveData나 RxJava와 같은 리액티브 프로그래밍 기법을 사용하여 구현됩니다. 데이터 변경이나 이벤트가 발생할 때 ViewModel 간의 상태 변화가 자동으로 반영되도록 바인딩이 설정됩니다.
1. 의존성 주입(Dependency Injection): 코드는 외부 의존성을 명시적으로 주입받아야 하며, 이를 통해 의존성을 쉽게 대체하거나 모의 객체(Mock Object)를 사용하여 테스트할 수 있습니다.
2. 의존성 역전 원칙(Inversion of Control): 코드는 상위 수준 모듈에 의존하지 않고 인터페이스에 의존해야 합니다. 이를 통해 코드의 결합도를 낮추고 테스트 용이성을 향상시킵니다.
3. 테스트 가능한 설계(Testable Design): 코드는 테스트를 수행하기 위해 필요한 상태를 쉽게 설정할 수 있어야 합니다. 예를 들어, 테스트용 데이터를 주입하는 것이 편리해야 합니다.
따라서 MVVM 아키텍처에서 ViewModel 간의 바인딩을 효율적으로 처리하고, 각 ViewModel이 테스트 가능한 방식으로 구현되면 단위 테스트 작성이 용이해집니다. 이는 코드의 품질을 향상시키고 애플리케이션의 신뢰성을 높이는 데 도움이 됩니다.
핵심: 단위 테스트 = 작은 단위 코드(함수, 메서드, 클래스) 테스트
11.1 모의 객체란?
모의 객체(Mock Object)는 소프트웨어 테스트에서 사용되는 가짜 객체로, 실제 객체의 동작을 모방하여 테스트하는 데 사용됩니다. 모의 객체는 일반적으로 특정 클래스 또는 인터페이스를 구현하며, 테스트 중에 호출되는 메서드에 대한 예상된 동작을 정의합니다.
1. 의존성 대체: 테스트 대상 코드가 의존하는 외부 객체를 대체하여 테스트의 격리를 유지합니다. 실제 외부 시스템이나 서비스와 상호 작용하는 대신에 테스트 중에 모의 객체가 호출되어 예상된 동작을 수행합니다.
2. 행위 검증: 특정 메서드가 호출되었는지, 호출된 횟수는 몇 번인지, 특정 인자와 함께 호출되었는지 등의 행위를 검증하는 데 사용됩니다. 모의 객체는 테스트 중에 호출된 메서드의 호출 횟수와 인자를 기록하고 검증할 수 있습니다.
3. 상태 확인: 모의 객체는 테스트 중에 상태를 확인하거나 가짜 데이터를 반환하는 데 사용될 수 있습니다. 이를 통해 테스트의 특정 시나리오를 쉽게 조작하고 테스트 결과를 예측할 수 있습니다.
모의 객체는 테스트의 격리를 유지하고 외부 의존성을 제어하는 데 중요한 역할을 합니다. 테스트가 실제 시스템에 의존하거나 외부 상태에 의존하지 않고도 격리된 환경에서 실행될 수 있도록 도와줍니다. 이를 통해 테스트의 안정성과 신뢰성을 높이고, 소프트웨어의 품질을 향상시킬 수 있습니다.
핵심: 모의 객체 = 가짜 객체
실제에 의존하지 않게 테스트할 때 사용
>> 모의 객체
11.2 "상위 수준 모듈에 의존하지 않고 인터페이스에 의존해야 한다"는 말의 의미는?
"상위 수준 모듈에 의존하지 않고 인터페이스에 의존해야 한다"는 것은 소프트웨어 디자인 원칙 중 하나인 "의존성 역전 원칙(Dependency Inversion Principle, DIP)"을 나타냅니다.
1. 상위 수준 모듈: 애플리케이션의 주요 기능을 구현하는 모듈 또는 클래스를 의미합니다. 상위 수준 모듈은 시스템의 핵심 비즈니스 로직이나 기능을 담당합니다.
2. 인터페이스: 클래스나 모듈이 제공하는 기능에 대한 추상화를 나타냅니다. 인터페이스는 구체적인 구현과는 분리되어 있으며, 코드의 결합도를 낮추고 유연성을 향상시킵니다.
의존성 역전 원칙은 상위 수준 모듈이 하위 수준 모듈에 의존하는 것이 아니라 둘 다 추상화된 인터페이스에 의존해야 한다는 개념을 강조합니다. 이는 다음과 같은 이점을 제공합니다:
-
상위 수준 모듈은 구체적인 구현에 대한 의존성을 갖지 않고 인터페이스를 통해 기능을 사용할 수 있습니다.
-
하위 수준 모듈은 인터페이스를 구현하여 상위 수준 모듈에 대한 특정 구현을 제공합니다.
-
변경이 발생할 때, 인터페이스는 유지되고 구현이 변경되어도 상위 수준 모듈은 영향을 받지 않습니다.
이러한 설계 원칙을 따르면 코드의 유연성과 확장성이 향상되며, 특히 단위 테스트를 작성하고 유지보수하는 데 도움이 됩니다. 따라서 상위 수준 모듈은 인터페이스에 의존하여 의존성 역전 원칙을 준수해야 합니다.
핵심: 모듈간 결합도와 의존성이 떨어져 코드 확장 수정, 테스트하는 데에 용이하다.
12. "View와 ViewModel 사이의 데이터 흐름을 자동화 한다"는 말이 무슨 의미인가?
"View와 ViewModel 사이의 데이터 흐름을 자동화" 한다는 말은 MVVM 아키텍처 패턴에서 데이터 바인딩을 통해 나타납니다. MVVM에서는 View와 ViewModel이 서로 연결되어 있으며, View에 표시되는 데이터는 ViewModel에서 관리됩니다. 이때 데이터의 변화나 업데이트가 있을 때, 이를 자동으로 View에 반영하는 것이 중요합니다.
데이터 바인딩은 XML 레이아웃 파일과 ViewModel 사이의 연결을 자동화하여 개발자가 직접 UI를 업데이트하거나 이벤트를 처리하는 코드를 작성하지 않아도 됩니다. 이를 통해 코드의 반복을 줄이고 개발 생산성을 향상시킬 수 있습니다.
1. 자동화된 UI 업데이트: ViewModel에서 데이터가 변경되면, 이를 자동으로 View에 반영하여 사용자에게 실시간 업데이트를 제공할 수 있습니다.
2. 코드의 간결화: XML 레이아웃 파일에서 바인딩 표현식을 사용하여 UI 요소와 ViewModel의 데이터를 간단하게 연결할 수 있습니다.
3. UI와 비즈니스 로직의 분리: ViewModel은 UI와 직접적으로 상호 작용하지만, UI 자체에 대한 의존성은 없습니다. 이를 통해 UI와 비즈니스 로직을 분리하여 유지보수성을 높입니다.
따라서 "View와 ViewModel 사이의 데이터 흐름을 자동화" 한다는 것은 MVVM 아키텍처에서 데이터 바인딩을 통해 View와 ViewModel 간의 연결을 자동으로 처리하고, UI 업데이트를 효율적으로 관리한다는 것을 의미합니다.
핵심: View -- 데이터 바인딩(자동화) -- ViewModel
13. 안드로이드 수명주기는 무엇인가?
안드로이드 앱은 다양한 수명 주기 상태를 가지며, 이를 통해 사용자와 시스템 사이의 상호작용을 관리합니다. 안드로이드의 수명 주기는 다음과 같은 주요 상태로 구성됩니다:
-
액티비티나 프래그먼트가 생성되었지만 아직 사용자에게 표시되지 않은 상태입니다.
-
onCreate() 메서드가 호출되며, 일반적으로 초기화 작업이 수행됩니다.
-
액티비티나 프래그먼트가 사용자에게 표시되었지만, 아직 포그라운드에서 실행되지는 않은 상태입니다.
-
onStart() 메서드가 호출되며, UI 초기화와 사용자 데이터 로드 등이 이루어집니다.
-
액티비티나 프래그먼트가 포그라운드에 있고 사용자와 상호작용이 가능한 상태입니다.
-
onResume() 메서드가 호출되며, 사용자 입력을 받고 애니메이션 및 애니메이션과 같은 화면 효과를 실행합니다.
-
다른 액티비티나 시스템 대화상자가 표시되어 현재 액티비티나 프래그먼트가 일부분만 보이는 상태입니다.
-
onPause() 메서드가 호출되며, 일시 정지 상태에 있는 동안 중요한 리소스를 해제하거나 저장해야 합니다.
-
액티비티나 프래그먼트가 사용자에게 더 이상 표시되지 않은 상태입니다.
-
onStop() 메서드가 호출되며, 시스템 리소스를 절약하기 위해 일반적으로 사용됩니다.
-
액티비티나 프래그먼트가 완전히 소멸된 상태입니다.
-
onDestroy() 메서드가 호출되며, 모든 리소스를 해제하고 최종 정리 작업을 수행합니다.
안드로이드 프레임워크는 앱의 현재 상태에 따라 이러한 수명 주기 콜백 메서드를 호출하여 앱이 적절하게 대응할 수 있도록 지원합니다. 앱의 수명 주기를 올바르게 관리하면 메모리 누수와 같은 문제를 방지하고 사용자 경험을 향상시킬 수 있습니다.
핵심: 수명(생명)주기 = 생성 / 시작 / 재개 / 일시정지 / 정지 / 종료
메서드 예) onCreate, onDestory
13.1 포그라운드란?
"포그라운드(foreground)"란 안드로이드에서 현재 사용자가 집중하고 있는 활성화된 앱 또는 화면을 의미합니다. 사용자가 앱을 실행하고 활동하고 있을 때, 해당 앱은 포그라운드에 있습니다.
안드로이드에서 포그라운드에 있는 앱은 사용자에게 현재 활동 중인 앱으로 보여지며, 사용자가 직접 상호작용할 수 있는 상태입니다. 포그라운드에 있는 앱은 시스템 리소스의 우선 순위를 높여서 CPU, 메모리 및 네트워크 등의 자원을 더 많이 할당받을 수 있습니다.
사용자가 앱을 실행하고 액티비티가 화면에 표시되면 해당 앱은 포그라운드에 들어가게 됩니다. 포그라운드에 있는 앱은 사용자가 다른 앱으로 전환하거나 홈 화면으로 돌아가더라도 계속 실행됩니다. 사용자가 앱을 백그라운드로 보내거나 해당 앱이 더 이상 화면에 표시되지 않으면 포그라운드에서 벗어납니다.
안드로이드에서는 포그라운드와 백그라운드의 구분을 통해 시스템 리소스를 효율적으로 관리하고, 사용자 경험을 최적화합니다.
핵심: 포그라운드 = 활성화된 앱 화면
14. ViewModel이 메모리 누출을 방지하는 이유는?
ViewModel이 메모리 누출을 방지하는 주요 이유는 다음과 같습니다:
1. 수명 주기 인식: ViewModel은 안드로이드의 수명 주기를 인식하고, 활동이나 프래그먼트와 같은 UI 컨트롤러의 수명 주기와 동기화됩니다. 이는 ViewModel이 UI 컨트롤러보다 오래 지속되는 경우에도 메모리 누출을 방지하는 데 도움이 됩니다.
2. 구성 변경에 대한 안정적인 데이터 보존: 화면 회전 또는 기기 구성 변경과 같은 이벤트가 발생하면, 안드로이드 프레임워크는 기본적으로 UI 컨트롤러를 다시 생성합니다. 그러나 ViewModel은 이러한 변경에 대해 영향을 받지 않고 데이터를 보존합니다. 따라서 ViewModel을 사용하면 데이터를 다시 로드하거나 복원할 필요가 없으므로 메모리 누출이 방지됩니다.
3. 액티비티 또는 프래그먼트 참조를 유지하지 않음: ViewModel은 액티비티나 프래그먼트와 같은 UI 컨트롤러에 대한 직접적인 참조를 유지하지 않습니다. 이는 액티비티나 프래그먼트가 메모리에서 제거될 때 ViewModel이 해당 참조를 계속 유지하지 않도록 하여 메모리 누출을 방지합니다.
4. 의존성 주입과 함께 사용: ViewModel을 의존성 주입 프레임워크와 함께 사용하면 더욱 효과적으로 메모리 누출을 방지할 수 있습니다. 의존성 주입을 사용하면 ViewModel을 생성할 때 필요한 의존성을 주입할 수 있으며, 이를 통해 ViewModel이 불필요한 객체 참조를 유지하지 않도록 할 수 있습니다.
5. 순수한 데이터 처리: ViewModel은 주로 UI 관련 데이터를 처리하고, UI 로직과 분리된 비즈니스 로직을 포함합니다. 이는 ViewModel이 간결하고 순수한 데이터 처리에 집중할 수 있도록 하여 메모리 누출 가능성을 줄여줍니다.
이러한 이유들로 ViewModel을 사용하면 안드로이드 앱에서 메모리 누출을 효과적으로 방지할 수 있습니다.
핵심: 직접적인 객체 참조(UI, 비즈니스로직)를 하지 않아서 메모리 누출 방지.
14.1 의존성 주입 프레임워크란 무엇인가?
의존성 주입(Dependency Injection) 프레임워크는 소프트웨어 개발에서 의존성을 주입하는 것을 자동화하는 도구나 라이브러리를 의미합니다. 이 프레임워크는 객체 간의 의존성을 관리하고, 필요한 객체를 생성하고 주입하여 개발자가 직접 객체를 생성하고 관리할 필요가 없도록 돕습니다.
1. 의존성 주입 컨테이너: 객체의 의존성을 관리하고, 필요한 객체를 생성하고 주입하는 역할을 합니다. 이를 통해 개발자는 객체 간의 의존성을 명시적으로 지정할 필요가 없으며, 의존성 주입 컨테이너가 이를 자동으로 처리합니다.
2. 의존성 주입 방법 지정: 의존성 주입 프레임워크는 여러 가지 방법을 통해 의존성을 주입할 수 있습니다. 예를 들어, 생성자 주입, 필드 주입, 메서드 주입 등의 방법을 지원할 수 있습니다.
3. 스코프 관리: 객체의 수명 주기를 관리하고, 필요에 따라 객체의 생성과 소멸을 관리합니다. 이를 통해 메모리 누수를 방지하고 성능을 최적화할 수 있습니다.
4. 테스트 용이성: 의존성 주입을 통해 객체 간의 결합도를 낮출 수 있으므로, 테스트하기 쉬운 코드를 작성할 수 있습니다. 의존성 주입을 통해 테스트용 객체를 주입하거나 목(mock) 객체를 사용하는 것이 가능해집니다.
대표적인 의존성 주입 프레임워크로는 Dagger, Guice, Spring 등이 있습니다. 이러한 프레임워크를 사용하면 코드의 유지 보수성을 높이고 의존성 관리를 간편하게 할 수 있습니다.
핵심: 의존성 주입 프레임워크 = 의존성 주입을 자동화하는 도구(라이브러리)
14.1.1 의존성 주입이란?
의존성 주입(Dependency Injection)은 소프트웨어 공학에서 객체 간의 의존성을 줄이고 코드의 재사용성, 유지 보수성, 테스트 용이성을 향상시키기 위한 설계 원칙 중 하나입니다.
일반적으로 객체 지향 프로그래밍에서는 클래스 간에 상호 작용이 필요한 경우 한 클래스가 다른 클래스의 인스턴스를 직접 생성하고 사용합니다. 이것은 객체 간의 강한 결합을 유발하며, 이로 인해 코드의 유연성이 저하될 수 있습니다.
의존성 주입은 이러한 문제를 해결하기 위해 객체 간의 결합도를 낮추고 의존성을 외부에서 주입하는 방식을 채택합니다. 주로 생성자, 메서드, 필드를 통해 의존성을 주입합니다.
1. 유연성: 의존성 주입을 통해 객체 간의 결합도를 낮출 수 있습니다. 따라서 코드 변경이 발생할 때 다른 클래스에 미치는 영향을 최소화하고, 시스템을 더욱 유연하게 변경할 수 있습니다.
2. 재사용성: 의존성 주입을 사용하면 독립적인 객체를 쉽게 재사용할 수 있습니다. 의존성 주입 컨테이너를 통해 필요한 객체를 주입하여 새로운 기능을 구현하거나 시스템을 확장하기 용이합니다.
3. 테스트 용이성: 의존성 주입을 통해 의존성을 외부에서 주입할 수 있으므로, 테스트할 때 모의 객체(Mock Object)나 테스트용 객체를 주입하여 테스트하기 쉽습니다.
4. 확장성: 의존성 주입을 사용하면 객체 간의 결합도를 낮추어 시스템의 확장성을 향상시킵니다. 새로운 기능을 추가하거나 기존 기능을 변경할 때 코드의 수정이 최소화되어 작업이 더욱 효율적으로 이루어집니다.
의존성 주입은 객체 지향 프로그래밍에서 중요한 개념으로, 코드의 유지 보수성과 확장성을 향상시키는 데 큰 도움을 줍니다.
핵심: 의존성 주입 = 의존을 외부에서 주입 (생성자, 메소드, 필드에서. 클래스간 X)
+ 생성자란?
-
생성자는 객체가 생성될 때 호출되는 특수한 메서드입니다.
-
클래스의 인스턴스를 초기화하고 객체의 상태를 설정하는 역할을 합니다.
-
생성자는 클래스와 동일한 이름을 가지며, 리턴 타입이 없습니다.
-
객체를 생성할 때 new 키워드와 함께 호출되며, 생성자가 호출될 때마다 새로운 객체가 생성됩니다.
-
Java에서 생성자는 다양한 형태로 오버로드될 수 있습니다. 즉, 매개변수의 타입, 개수, 순서에 따라 다른 생성자를 정의할 수 있습니다.
public class Person {
private String name;
private int age;
// 기본 생성자
public Person() {
this.name = "Unknown";
this.age = 0;
}
// 매개변수를 받는 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
핵심: 생성자 = 객체 생성시 초기화 역할
++ 오버로드란?
"오버로드(Overloading)"는 객체 지향 프로그래밍 언어에서 메서드나 생성자의 이름은 같지만 매개변수의 유형, 개수, 순서 등이 다른 여러 버전을 정의하는 것을 말합니다. 즉, 같은 이름의 메서드나 생성자를 여러 개 정의하여 다양한 매개변수에 대응할 수 있습니다.
오버로드의 핵심 아이디어는 메서드나 생성자의 기능은 같지만 입력값이 다를 때 여러 버전을 사용할 수 있도록 하는 것입니다. 이를 통해 코드의 가독성을 높이고, 개발자가 사용자 편의성을 높일 수 있습니다.
예를 들어, 다음은 오버로드된 메서드의 예시입니다:
public class Calculator {
// 정수형 두 개를 더하는 메서드
public int add(int a, int b) {
return a + b;
}
// 실수형 두 개를 더하는 메서드
public double add(double a, double b) {
return a + b;
}
// 세 개의 정수를 더하는 메서드
public int add(int a, int b, int c) {
return a + b + c;
}
}
위 예시에서는 add 메서드가 세 번 오버로드되었습니다. 첫 번째는 정수형 두 개를 더하고, 두 번째는 실수형 두 개를 더하며, 세 번째는 정수형 세 개를 더합니다.
이렇게 오버로드된 메서드를 호출할 때는 전달하는 인자에 따라 알맞은 버전이 호출됩니다. 오버로드는 Java뿐만 아니라 다른 많은 객체 지향 프로그래밍 언어에서 지원되는 기능입니다.
핵심: 오버로드 = 이름은 같지만 입력(매개변수)이 다르다
>> 오버로딩 & 오버라이딩
+ 필드란?
-
필드는 클래스 내부에서 정의된 변수를 의미합니다.
-
클래스의 상태나 속성을 나타내며, 객체의 데이터를 저장합니다.
-
필드는 클래스의 멤버 변수로서 클래스 내부에 선언되며, 객체의 상태를 나타내는 데이터를 저장하거나 참조합니다.
-
필드는 클래스 내부의 어떤 메서드에서든지 접근할 수 있습니다. 필드에 대한 접근 제어자를 사용하여 접근 권한을 설정할 수 있습니다.
핵심: 필드 = 클래스 안 변수
++ 접근 제어자란?
필드(Field)에 대한 접근 제어자는 해당 필드에 접근할 수 있는 범위를 지정하는 데 사용됩니다. 접근 제어자는 객체 지향 프로그래밍에서 캡슐화(Encapsulation)의 개념을 구현하고, 데이터의 은닉성을 보장하는 데 중요한 역할을 합니다. 다음은 주요한 접근 제어자들입니다:
-
public 접근 제어자는 해당 필드에 대한 외부 접근을 허용합니다.
-
다른 클래스에서 어디서든 해당 필드에 접근할 수 있습니다.
-
protected 접근 제어자는 동일한 패키지 내의 클래스와 해당 클래스를 상속한 하위 클래스에서만 필드에 접근할 수 있습니다.
-
패키지 외부의 클래스에서는 접근할 수 없습니다.
-
만약 접근 제어자가 명시되어 있지 않으면, 해당 필드는 기본(default) 접근 제어자를 갖습니다.
-
기본 접근 제어자는 동일한 패키지 내의 클래스에서만 필드에 접근할 수 있습니다.
-
private 접근 제어자는 해당 클래스 내에서만 필드에 접근할 수 있습니다.
-
다른 클래스에서는 접근할 수 없으며, 데이터 은닉성을 보장합니다.
접근 제어자를 적절히 활용하여 필드의 접근 범위를 제한함으로써 클래스의 캡슐화를 강화하고, 데이터의 무결성과 보안을 유지할 수 있습니다. 이는 객체 지향 프로그래밍의 핵심 개념 중 하나인 정보 은닉(Encapsulation)을 실현하는 데 중요한 요소입니다.
핵심: 접근제어자 예) public, protected, private
>> 자바 - 접근제어자 public, private, protected 및 default
14.1.2 컨테이너란?
'컨테이너'는 여러 객체나 요소를 담는 그릇이나 용기를 의미합니다. 소프트웨어 개발에서의 컨테이너는 객체나 리소스를 관리하고 제공하는 환경을 가리킵니다.
의존성 주입 컨테이너에서의 '컨테이너'는 객체의 생성, 관리, 의존성 주입 등을 담당하는 런타임 환경을 지칭합니다. 이 컨테이너는 애플리케이션의 구성 요소들을 관리하고, 필요에 따라 적절한 시점에 객체를 생성하고 의존성을 주입합니다.
일반적으로 의존성 주입 컨테이너는 애플리케이션의 생명주기 동안 필요한 객체들을 생성하고 관리하는데 사용됩니다. 이를 통해 개발자는 객체의 생성과 관리에 집중하기보다는 비즈니스 로직에 집중할 수 있습니다.
핵심: 컨테이너 = 객체, 리소스 등 관리 환경
+ 런타임 환경이란?
런타임 환경(Runtime Environment)은 컴퓨터 프로그램이 실행되는 동안의 환경을 나타냅니다. 프로그램이 실행되는 동안 사용되는 메모리, 프로세스 제어, 입출력 작업, 네트워크 통신 등과 관련된 모든 것을 포함합니다.
1. 메모리 관리: 프로그램이 실행될 때 필요한 메모리 공간을 할당하고 해제합니다.
2. 프로세스 제어: 프로그램이 실행될 때 프로세스의 생성, 종료, 관리를 담당합니다.
3. 입출력 관리: 사용자와의 상호작용을 위한 입력 및 출력 작업을 처리합니다.
4. 자원 관리: 시스템 자원(파일, 네트워크 연결 등)을 관리하고 할당합니다.
5. 예외 처리: 프로그램 실행 중 발생하는 예외를 처리하고 프로그램의 안정성을 유지합니다.
6. 스레드 관리: 다중 스레드 환경에서의 스레드 생성, 스케줄링, 동기화를 관리합니다.
7. 네트워크 통신: 네트워크를 통한 통신을 처리하고 관리합니다.
런타임 환경은 프로그램이 실행되는 동안에만 존재하며, 프로그램의 실행이 종료되면 소멸됩니다. 언어나 플랫폼에 따라 다양한 런타임 환경이 존재하며, 각각의 환경은 해당 언어나 플랫폼에 특화된 기능을 제공합니다.
핵심: 런타임 환경 = 프로그램 실행 동안의 환경
>> 런타임
15. android.lifecycle.ViewModel 클래스가 무엇인가?
androidx.lifecycle.ViewModel 클래스는 안드로이드 Jetpack의 일부로 제공되는 클래스로, 안드로이드 앱의 UI 관련 데이터를 관리하고 화면 회전 및 구성 변경과 같은 구성 변경 시에 데이터를 유지하는 데 사용됩니다.
일반적으로 화면 회전과 같은 구성 변경이 발생하면, 액티비티나 프래그먼트는 다시 생성되어 기존의 데이터를 잃게 됩니다. 이는 사용자 경험을 저하시키고 데이터 손실로 이어질 수 있습니다. ViewModel 클래스는 이러한 문제를 해결하기 위해 디자인되었습니다.
1. 구성 변경 시 데이터 보존: ViewModel은 화면 회전 및 다른 구성 변경 시에도 데이터를 유지합니다. 이는 액티비티나 프래그먼트의 생명주기와 독립적으로 동작합니다.
2. 메모리 누출 방지: ViewModel은 액티비티나 프래그먼트와 같은 UI 컴포넌트의 생명주기와 별도로 관리되므로, 메모리 누출을 방지합니다.
3. 비즈니스 로직 분리: ViewModel은 UI 관련 로직과 비즈니스 로직을 분리하여 애플리케이션의 구조를 개선합니다.
ViewModel 클래스는 안드로이드의 AAC(Android Architecture Components) 라이브러리의 일부로 제공되며, MVVM(Model-View-ViewModel) 아키텍처에서 사용됩니다. 일반적으로 데이터를 로드하고 보유하는 데 사용되며, LiveData와 결합하여 데이터의 변경을 관찰하고 UI를 업데이트하는 데 자주 사용됩니다.
핵심: android.lifecycle.ViewModel = 데이터 유지를 위한 Jetpack 클래스
>> [ViewModel] 1. View의 Lifecycle 동안 데이터를 유지시켜 주는 클래스
15.1 AAC란 무엇인가?
AAC는 Android Architecture Components의 약어로, 안드로이드 앱의 아키텍처를 개선하고 개발을 단순화하기 위해 구글에서 제공하는 라이브러리 모음입니다. AAC는 안드로이드 앱의 구성요소인 액티비티, 프래그먼트, 서비스 등을 더욱 효율적으로 관리하고, 생명주기를 관리하며, 데이터의 변화를 관찰하는 데 도움을 줍니다.
1. Lifecycle: Lifecycle 클래스는 앱의 구성요소의 생명주기를 관리하는 데 사용됩니다. 이를 통해 메모리 누출을 방지하고 액티비티 및 프래그먼트의 생명주기 이벤트를 관찰할 수 있습니다.
2. ViewModel: ViewModel 클래스는 UI 관련 데이터의 저장 및 관리를 담당합니다. 화면 회전 및 구성 변경과 같은 이벤트가 발생해도 데이터가 유지되도록 지원하며, UI 컨트롤러와 비즈니스 로직을 분리하여 앱의 구조를 개선합니다.
3. LiveData: LiveData는 관찰 가능한 데이터 홀더로, 데이터의 변경을 관찰하고 UI를 업데이트하는 데 사용됩니다. 생명주기를 인식하여 데이터를 관찰하고, UI 구성요소가 활성 상태일 때만 업데이트를 전달합니다.
4. Room: Room은 SQLite 데이터베이스에 대한 추상화 레이어를 제공하는 라이브러리입니다. Room은 데이터베이스와의 상호 작용을 단순화하고 유지보수성을 높이며, SQL 쿼리의 오류를 컴파일 타임에 확인할 수 있습니다.
5. Navigation: Navigation은 사용자의 앱 내 탐색을 관리하는 데 사용되는 구성요소입니다. Navigation은 화면 간 이동을 단순화하고 백 스택 관리를 통해 사용자 경험을 향상시킵니다.
6. WorkManager: WorkManager는 비동기 작업을 예약하고 관리하는 데 사용됩니다. 백그라운드에서 실행되는 작업을 안정적으로 처리하고, 앱의 백그라운드 작업 관리를 단순화합니다.
AAC는 안드로이드 앱의 아키텍처를 개선하여 유지보수성을 향상시키고, 개발 생산성을 향상시키는 데 도움을 줍니다.
핵심: AAC = 앱 관련 구글 제공 라이브러리 예) LiveData, Room, Navigation
>> ACC란?
15.1.1 서비스란?
안드로이드에서의 서비스(Service)는 백그라운드에서 오래 실행되는 작업을 수행하기 위해 사용되는 구성 요소입니다. 주로 사용자 인터페이스(UI)를 제공하지 않고, 백그라운드에서 실행되는 작업을 처리하거나 백그라운드에서 계속 실행되어야 하는 작업을 관리합니다.
1. 백그라운드 작업 처리: 서비스는 메인 스레드가 아닌 백그라운드 스레드에서 작업을 처리합니다. 따라서 사용자와 상호작용하는 UI를 제공하지 않고도 시간이 많이 소요되는 작업을 수행할 수 있습니다.
2. 오랜 시간 실행: 서비스는 사용자의 명시적인 요청 없이도 오랜 시간 동안 실행될 수 있습니다. 예를 들어, 음악 재생, 파일 다운로드, 데이터 동기화 등과 같은 작업을 수행하는 데 사용될 수 있습니다.
3. 포그라운드 및 백그라운드 실행: 서비스는 포그라운드에서 실행될 수도 있고, 백그라운드에서 실행될 수도 있습니다. 포그라운드 서비스는 사용자에게 알림을 통해 현재 진행 중인 작업을 표시하고, 사용자가 서비스를 중지시키지 않도록 보장합니다.
안드로이드에서는 서비스를 시작하거나 바인딩하는 두 가지 주요 방법으로 사용할 수 있습니다.
-
시작된 서비스(Started Service): startService() 메서드를 사용하여 시작된 서비스를 실행할 수 있습니다. 이 서비스는 startService()를 호출한 애플리케이션 컴포넌트와 독립적으로 실행되며, 작업이 완료되면 명시적으로 중지해야 합니다.
-
바운드 서비스(Bound Service): bindService() 메서드를 사용하여 바운드 서비스에 연결할 수 있습니다. 이 서비스는 클라이언트-서버 인터페이스를 제공하고, 클라이언트가 서비스에 바인딩되어야만 작업을 수행합니다. 클라이언트와 서비스 사이에 통신이 가능합니다.
핵심: 서비스 = 백그라운드 오랜 작업 위함
예) 음악재생, 파일다운
>> 안드로이드 4대 요소 Acitivity, Service, Broadcast Receiver, Content Provider 정리
+ 서비스를 바인딩한다는 것은?
안드로이드에서 서비스를 바인딩한다는 것은 클라이언트 앱(액티비티, 서비스 등)가 서비스에 연결하여 서비스의 기능을 사용할 수 있도록 하는 것을 의미합니다. 서비스를 바인딩하면 서비스의 메서드를 호출하고 서비스와 데이터를 주고받을 수 있습니다.
서비스를 바인딩하는 데에는 일반적으로 bindService() 메서드를 사용합니다. 이 메서드를 호출하면 서비스와 클라이언트 간의 연결이 설정되며, ServiceConnection 인터페이스를 통해 서비스와 통신할 수 있는 인터페이스를 제공합니다.
1. 기능 공유: 서비스를 바인딩하여 여러 구성 요소가 해당 서비스의 기능을 공유하고 사용할 수 있습니다.
2. 통신: 서비스를 바인딩하면 클라이언트가 서비스와 통신할 수 있습니다. 클라이언트는 서비스의 메서드를 호출하여 데이터를 전달하고, 서비스는 클라이언트에게 데이터를 반환할 수 있습니다.
3. 동기화: 바인딩된 서비스는 클라이언트와 바인딩된 상태에서만 작동하기 때문에, 서비스의 생명주기는 클라이언트의 생명주기에 영향을 받습니다. 이를 통해 서비스의 동작을 클라이언트의 요구에 따라 동기화할 수 있습니다.
서비스를 바인딩하려면 클라이언트가 bindService() 메서드를 호출하고, 바인딩된 서비스와의 통신을 처리하기 위해 ServiceConnection 인터페이스를 구현해야 합니다. 이후에는 서비스와 클라이언트 간의 통신을 위해 정의된 인터페이스를 사용하여 데이터를 주고받을 수 있습니다.
핵심: 서비스 바인딩 = 서비스의 기능을 사용한다
액티비티 -- 바인딩 -- 서비스
>> BindService 간단 구현 및 사용법(서비스와 액티비티 통신)
++ ServiceConnection 인터페이스란?
ServiceConnection 인터페이스는 안드로이드 앱의 구성 요소(주로 액티비티)와 서비스 간의 통신을 관리하기 위한 콜백 인터페이스입니다. 이 인터페이스를 구현하여 서비스와의 연결 상태 변경 및 통신 이벤트를 처리할 수 있습니다.
1. onServiceConnected(ComponentName name, IBinder service): 서비스와 성공적으로 연결되었을 때 호출됩니다. 이 메서드는 서비스에서 제공하는 IBinder 인터페이스를 통해 서비스와 통신할 수 있는 인터페이스를 받습니다.
2. onServiceDisconnected(ComponentName name): 서비스와의 연결이 예기치 않게 끊어졌을 때 호출됩니다. 이 메서드는 일반적으로 서비스와의 연결이 끊겼을 때 클라이언트에서 적절한 조치를 취할 수 있도록 합니다.
이 인터페이스를 구현하여 서비스와의 상호작용을 관리하고, 서비스와 클라이언트 간의 통신을 처리할 수 있습니다. 일반적으로는 bindService() 메서드를 호출할 때 ServiceConnection 인터페이스의 인스턴스를 전달하여 서비스와의 연결을 설정합니다. 그러면 시스템이 연결 상태 변경을 감지하고, 이벤트가 발생할 때마다 ServiceConnection 메서드가 호출됩니다.
핵심: ServiceConnection = 액티비티, 서비스 간 통신 관리 콜백 인터페이스
>> 바인딩된 서비스
15.1.2 추상화 레이어란?
추상화 레이어는 소프트웨어에서 하위 수준의 세부 사항을 숨기고 상위 수준의 추상화를 제공하는 것을 말합니다. 이것은 소프트웨어의 복잡성을 줄이고 코드의 재사용성을 높이며, 개발자가 구현의 세부 사항에 대해 고려하지 않고도 코드를 작성할 수 있도록 합니다.
1. 세부 사항 숨기기: 하위 수준의 구현 세부 사항을 감춥니다. 이렇게 하면 상위 수준의 모듈이나 클래스가 하위 수준의 변경 사항에 영향을 받지 않습니다.
2. 인터페이스 제공: 추상화 레이어는 하위 수준의 구현 세부 사항을 숨기고 상위 수준의 인터페이스를 제공합니다. 이를 통해 클라이언트 코드는 실제 구현 세부 사항을 알 필요 없이 인터페이스를 통해 상호 작용할 수 있습니다.
3. 복잡성 감소: 추상화를 통해 복잡성을 감소시키고 코드를 간결하게 유지할 수 있습니다. 이는 코드의 가독성을 향상시키고 유지보수를 용이하게 만듭니다.
추상화 레이어는 다양한 소프트웨어 컴포넌트에서 발견될 수 있습니다. 예를 들어, 데이터베이스 추상화 레이어는 데이터베이스에 대한 접근을 단순화하고, 네트워크 추상화 레이어는 네트워크 통신을 관리하고 단순화합니다. 이러한 추상화 레이어는 소프트웨어 개발 과정에서 중요한 역할을 합니다.
핵심: 추상화 레이어 = 세부사항 숨기는 레이어
+ 레이어란?
소프트웨어에서 "레이어(layer)"는 일종의 구성 요소 그룹을 가리키는 개념입니다. 이러한 레이어들은 일반적으로 서로 다른 추상화 수준에서 서로 다른 역할을 수행하며, 소프트웨어 시스템을 구조화하고 유지 관리하기 위해 사용됩니다.
레이어는 소프트웨어 아키텍처에서 주로 사용되며, 보통은 상위 수준에서 하위 수준으로 나뉘어집니다. 각 레이어는 특정한 책임과 역할을 가지며, 다른 레이어와의 상호 작용을 통해 전체 시스템이 동작합니다.
1. 프레젠테이션 레이어(Presentation Layer): 사용자 인터페이스(UI)와 상호 작용하며, 사용자에게 정보를 표시하고 사용자 입력을 처리합니다. 주로 액티비티, 프래그먼트, 뷰 등으로 구성됩니다.
2. 비즈니스 레이어(Business Layer): 비즈니스 로직을 처리하고, 업무 규칙을 구현합니다. 데이터의 유효성 검사, 데이터 처리, 업무 규칙 적용 등을 수행합니다. 서비스, 모델, 유틸리티 클래스 등이 이 레이어에 속합니다.
3. 데이터 액세스 레이어(Data Access Layer): 데이터베이스나 외부 API와의 상호 작용을 관리하며, 데이터의 저장, 수정, 검색, 삭제 등의 작업을 수행합니다. DAO(Data Access Object), Repository 등이 이 레이어에 속합니다.
4. 인프라스트럭처 레이어(Infrastructure Layer): 하드웨어나 네트워크와의 상호 작용을 처리하며, 시스템의 기술적인 부분을 담당합니다. 데이터베이스 연결, 네트워크 통신, 파일 시스템 액세스 등을 다룹니다.
이러한 레이어는 서로 다른 책임과 역할을 갖고 있으며, 각 레이어는 높은 수준의 추상화를 제공하여 시스템의 복잡성을 관리하고 유지보수성을 향상시킵니다. 또한 각 레이어는 독립적으로 개발, 테스트, 유지보수할 수 있도록 분리되어야 합니다.
핵심: 레이어 = 구성요소 그룹
예)
프레젠테이션 레이어 = 액티비티, 프래그먼트
데이터 엑세스 레이어 = DAO, Repository
>> 레이어 아키텍처
15.1.3 백 스택 관리란?
백 스택 관리는 사용자가 앱 내에서 이전에 방문한 화면들의 순서를 추적하고 관리하는 것을 의미합니다. 주로 모바일 앱이나 웹 애플리케이션에서 사용됩니다.
일반적으로 사용자가 앱 내에서 다양한 화면을 탐색하면서 이전 화면으로 돌아가거나 새로운 화면으로 이동합니다. 이 때, 사용자가 이전에 방문한 화면들의 정보를 기록하고 관리하는 것이 백 스택 관리입니다.
백 스택은 일종의 스택 자료구조로, 사용자가 앱 내에서 화면을 탐색할 때마다 현재 화면을 스택에 추가하고, 이전 화면으로 돌아갈 때마다 스택에서 화면을 팝(pop)하여 이동하는 구조입니다. 이를 통해 사용자는 이전 화면으로 쉽게 돌아갈 수 있고, 앱의 탐색 경로를 간편하게 관리할 수 있습니다.
안드로이드 앱에서는 FragmentManager를 통해 백 스택 관리를 수행합니다. 사용자의 탐색 히스토리를 관리하고, 화면 간 전환을 스택의 형태로 처리하여 사용자 경험을 향상시킵니다.
핵심: 백 스택 관리 = 이전 화면 추적
+ 스택 자료구조란?
스택(Stack)은 후입선출(LIFO, Last In, First Out) 원칙에 따라 데이터를 저장하고 접근하는 선형 자료구조입니다. 스택은 데이터를 저장하는 컨테이너로, 가장 최근에 삽입된 데이터가 가장 먼저 제거됩니다.
1. Push: 스택에 데이터를 추가하는 연산입니다. 새로운 데이터는 스택의 맨 위에 삽입됩니다.
2. Pop: 스택에서 데이터를 제거하고 반환하는 연산입니다. 가장 위에 있는 데이터가 제거됩니다.
3. Peek (Top): 스택의 맨 위에 있는 데이터를 반환합니다. 데이터를 제거하지 않고도 확인할 수 있습니다.
4. isEmpty: 스택이 비어 있는지 여부를 확인하는 연산입니다.
5. Size: 스택에 저장된 데이터의 개수를 반환합니다.
스택은 컴퓨터 과학에서 다양한 응용 분야에 사용됩니다. 예를 들어, 함수 호출과 복귀에 대한 메모리를 관리하는 데에 사용되며, 웹 브라우저의 "뒤로 가기" 기능이나 텍스트 편집기의 "되돌리기" 기능 등에서도 사용됩니다. 또한, 재귀 알고리즘 등 다양한 알고리즘에서 스택이 중요한 역할을 합니다.
핵심: 스택 자료구조 = 후입선출
15.1.4 "UI 구성요소가 활성 상태일 때만 업데이트를 전달한다"라는게 무슨 의미인가?
"UI 구성요소가 활성 상태일 때만 업데이트를 전달한다"는 의미는 일반적으로 Android 앱의 UI 구성요소(예: 액티비티, 프래그먼트)가 화면에 표시되어 사용자와 상호작용할 수 있는 상태일 때만 데이터의 변경 사항을 UI에 반영하도록 하는 것을 의미합니다.
예를 들어, Android 앱에서 LiveData를 사용할 때, LiveData는 생명주기 인식을 통해 관찰 가능한 데이터를 제공합니다. 이렇게 LiveData에 연결된 UI 구성요소는 활성 상태일 때만 LiveData의 변경 사항을 감지하고 업데이트를 수신합니다. 활성 상태가 아닌 경우, 예를 들어 화면이 백그라운드에 있거나 다른 액티비티가 화면을 가리고 있는 경우에는 데이터의 변경을 감지하지 않습니다.
이러한 동작은 메모리와 성능을 효율적으로 관리하기 위한 것입니다. 활성 상태가 아닌 UI 구성요소는 데이터의 변경을 받아들일 필요가 없으며, 이를 통해 자원을 절약하고 불필요한 UI 업데이트를 방지할 수 있습니다. 이는 앱의 반응성을 향상시키고 배터리 수명을 연장하는 데 도움이 됩니다.
핵심: 사용자 상호작용 가능 상태(활성상태)에서 변경 사항을 감지(LiveData)하여 업데이트한다.
+ 활성상태란?
"활성 상태(Active State)"는 Android 앱의 UI 구성 요소가 현재 사용자에게 보이고 상호 작용할 수 있는 상태를 말합니다. 예를 들어, 화면에 표시된 액티비티나 프래그먼트는 활성 상태에 있습니다. 사용자가 해당 화면을 보고 상호 작용할 수 있는 동안, 해당 UI 구성 요소는 활성 상태입니다.
활성 상태에 있는 UI 구성 요소는 사용자의 입력을 받아들이고 처리할 수 있습니다. 또한, 활성 상태에 있는 UI 구성 요소는 화면에 변경 사항을 표시하고, 데이터의 업데이트를 반영할 수 있습니다.
반면에, 다른 앱으로 인해 화면이 가려진 경우나, 사용자가 다른 화면으로 이동한 경우에는 해당 UI 구성 요소는 비활성 상태가 될 수 있습니다. 이 경우에는 UI 구성 요소가 사용자와 상호 작용할 수 없고, 화면에 표시되는 변경 사항을 감지할 필요가 없습니다. 이런 상황에서는 자원을 절약하기 위해 해당 UI 구성 요소는 비활성 상태로 간주됩니다.
따라서, "활성 상태"는 UI 구성 요소가 현재 사용자에게 보이고 사용자와 상호 작용할 수 있는 상태를 가리킵니다.
핵심: 활성 상태 = 사용자 상호작용 가능 상태
16. AndroidX란 무엇인가?
AndroidX는 안드로이드 앱을 개발하기 위한 공식 지원 라이브러리 세트입니다. 이전에는 안드로이드 지원 라이브러리(Android Support Library)로 알려진 AndroidX는 안드로이드 앱을 더 쉽게 개발하고 유지 보수할 수 있도록 도와줍니다.
AndroidX는 안드로이드 개발에 필요한 다양한 기능을 제공하며, 이전 지원 라이브러리보다 개선된 기능과 성능을 제공합니다. AndroidX는 안드로이드 앱의 하위 호환성을 제공하면서도 새로운 안드로이드 버전의 기능을 활용할 수 있게 해줍니다.
AndroidX에는 다음과 같은 서브 라이브러리가 포함되어 있습니다:
1. AndroidX Core Libraries: 안드로이드 앱의 핵심 기능을 포함하고 있으며, 안드로이드 플랫폼의 핵심 기능과 상호 작용하는 데 사용됩니다.
2. AndroidX Appcompat Libraries: 오래된 버전의 안드로이드와의 호환성을 제공하며, 최신 기능을 오래된 안드로이드 버전에서도 사용할 수 있게 해줍니다.
3. AndroidX Lifecycle Libraries: Android 앱의 라이프사이클을 관리하고, UI 컴포넌트의 생명주기와 데이터를 관리하는 데 사용됩니다.
4. AndroidX Room Libraries: 안드로이드 앱에서 SQLite 데이터베이스와의 작업을 쉽게 할 수 있도록 도와주는 ORM(Object Relational Mapping) 라이브러리입니다.
6. AndroidX Navigation Libraries: 네비게이션 구성 요소를 사용하여 사용자의 앱 내 탐색을 관리하는 데 사용됩니다.
등등 다양한 라이브러리가 포함되어 있으며, 안드로이드 앱을 개발할 때 이러한 AndroidX 라이브러리를 활용하여 개발 생산성을 향상시킬 수 있습니다.
핵심: AndroidX = 안드로이드 앱 개발 위한 라이브러리
16.1 ORM이란 무엇인가?
ORM(객체-관계 매핑)은 객체 지향 프로그래밍 언어에서 사용되는 객체와 관계형 데이터베이스(예: MySQL, PostgreSQL, SQLite 등) 사이의 데이터 변환을 자동화하는 프로그래밍 기법이다.
일반적으로 객체 지향 프로그래밍에서는 객체 간의 관계를 표현하고 데이터를 객체로 캡슐화하여 코드를 구성한다. 그러나 관계형 데이터베이스는 테이블 형식으로 데이터를 저장하고 관리한다. 이러한 객체와 관계형 데이터베이스 간에는 구조적인 차이가 있기 때문에 데이터를 변환하고 매핑하는 작업이 필요하다.
ORM은 이러한 객체와 관계형 데이터베이스 간의 매핑 작업을 자동화하여 개발자가 별도의 SQL 쿼리를 작성하지 않고도 객체를 데이터베이스에 저장하고 검색할 수 있게 해준다. ORM은 데이터베이스의 테이블을 객체로, 테이블의 열을 객체의 속성으로 매핑한다.
1. SQL 쿼리를 직접 작성할 필요가 없어 개발 생산성을 향상시킨다.
2. 데이터베이스 구조의 변경에 대한 유연성을 제공한다.
3. 객체 지향 프로그래밍 언어의 장점을 최대한 활용하여 코드를 작성할 수 있다.
일반적으로 ORM 프레임워크에는 Hibernate(Java), Entity Framework(.NET), Django ORM(Python), Sequelize(Node.js) 등이 있다. 이러한 ORM 프레임워크를 사용하면 개발자는 객체 지향 코드를 작성하면서 데이터베이스와의 상호 작용을 쉽게 처리할 수 있다.
핵심: ORM = 객체와 관계형DB를 매핑
DB의 테이블은 객체, 열은 객체의 속성으로.
16.2 리사이클러뷰는 무엇인가?
리사이클러뷰(RecyclerView)는 안드로이드 앱에서 리스트나 그리드와 같은 데이터 목록을 표시하는 데 사용되는 위젯(Widget)입니다. 리사이클러뷰는 안드로이드에서 반복적으로 사용되는 리스트나 그리드 형태의 데이터를 효율적으로 관리하고 표시할 수 있도록 도와줍니다.
리사이클러뷰는 기본적으로 뷰(View)를 재사용하여 메모리 사용량을 최적화하고 스크롤 시 부드러운 사용자 경험을 제공합니다. 이를 통해 대규모 데이터 목록을 효율적으로 처리할 수 있습니다.
리사이클러뷰는 아이템을 표시하기 위한 뷰홀더(ViewHolder) 패턴을 사용합니다. 뷰홀더 패턴은 화면에 보이는 아이템들의 뷰를 재활용하여 성능을 향상시키는데 도움이 됩니다.
1. 다양한 레이아웃 관리자(LayoutManager)를 사용하여 리스트, 그리드, 스태거 그리드 등 다양한 레이아웃을 표현할 수 있습니다.
2. 아이템의 추가, 제거, 이동, 수정 등을 동적으로 처리할 수 있습니다.
3. 아이템 클릭, 롱클릭 등의 이벤트를 처리할 수 있습니다.
4. 데이터의 변경 사항을 감지하여 자동으로 화면을 갱신할 수 있습니다.
리사이클러뷰는 안드로이드에서 많은 앱에서 사용되는 중요한 UI 컴포넌트 중 하나이며, 대부분의 데이터 목록 표시에 유용하게 사용됩니다.
핵심: 리사이클러뷰 = 목록(리스트, 그리드) 표시 위젯
>> 리사이클러뷰
16.2.1 그리드와 스태거 그리드란?
그리드(Grid)와 스태거 그리드(Staggered Grid)는 안드로이드에서 데이터를 표시하는 레이아웃 형태 중 두 가지입니다.
1. 그리드(Grid):
그리드 레이아웃은 데이터를 일정한 행과 열의 격자 형태로 표시하는 방식입니다. 각 아이템은 격자의 셀에 배치되며, 각 셀의 크기는 동일합니다. 그리드는 일반적으로 이미지 또는 상품 목록과 같이 균일한 크기의 데이터를 표시할 때 사용됩니다.
스태거드 그리드 레이아웃은 그리드와 유사하지만, 각 아이템의 높이가 서로 다를 수 있습니다. 즉, 각 행의 높이가 일정하지 않고, 아이템의 높이가 다를 수 있습니다. 이로 인해 각 행의 아이템이 서로 겹치거나, 다른 행보다 더 긴 아이템이 있을 수 있습니다. 스태거드 그리드는 이미지나 카드 레이아웃과 같이 다양한 크기의 데이터를 효과적으로 표시할 때 유용합니다.
그리드와 스태거드 그리드는 안드로이드 앱에서 데이터를 효율적으로 표시하고 사용자 경험을 개선하는 데 사용됩니다. 유연한 레이아웃 옵션을 제공하여 다양한 종류의 데이터를 다룰 수 있습니다.
핵심:
그리드 = 격자
스태거 그리드 = 높이 다를 수 있는 격자
16.2.2 뷰홀더란?
뷰홀더(ViewHolder) 패턴은 안드로이드에서 사용되는 패턴 중 하나로, 주로 리스트나 그리드와 같은 목록 형태의 데이터를 효율적으로 표시하기 위해 사용됩니다. 뷰홀더 패턴은 리스트나 그리드와 같은 목록에서 발생하는 뷰의 재사용과 관련이 있습니다.
안드로이드에서는 리스트나 그리드와 같은 목록을 표시할 때 각 아이템의 뷰를 생성하고 관리해야 합니다. 하지만 매번 새로운 뷰를 생성하는 것은 비효율적이며 성능에도 문제를 일으킬 수 있습니다. 따라서 뷰홀더 패턴을 사용하여 이러한 문제를 해결합니다.
1. 목록의 각 아이템 뷰를 생성할 때 뷰의 구성 요소를 찾고, 데이터를 설정합니다.
2. 생성된 뷰를 리스트나 그리드에 표시합니다.
3. 사용자가 스크롤하여 뷰가 화면을 벗어날 때, 해당 뷰를 다시 사용할 수 있도록 뷰를 재활용합니다.
뷰홀더 패턴을 사용하면 매번 뷰를 새로 생성하지 않고, 이미 생성된 뷰를 재활용하여 성능을 향상시킬 수 있습니다. 이를 통해 메모리와 처리 속도를 효율적으로 관리할 수 있으며, 안드로이드의 리사이클러뷰와 같은 위젯에서 많이 활용됩니다.
핵심: 뷰홀더 = 목록 형태 데이터 재사용
>> ViewHolder Pattern에 대해 알아보기
16.2.3 롱클릭이란?
롱클릭(Long Click)은 사용자가 특정 뷰나 요소를 일정한 시간 동안(일반적으로 1초 이상) 누르고 있을 때 발생하는 이벤트입니다. 사용자가 화면의 특정 요소를 클릭하거나 터치하는 것보다 더 긴 시간 동안 해당 요소를 누르고 있으면 롱클릭 이벤트가 발생합니다.
롱클릭 이벤트는 주로 사용자 인터페이스(UI)에서 긴 시간 동안 눌러야 하는 작업을 트리거하기 위해 사용됩니다. 예를 들어, 리스트의 항목을 삭제하거나 수정하는 기능, 이미지를 확대하여 보여주는 기능 등에 사용될 수 있습니다.
안드로이드에서는 롱클릭 이벤트를 처리하기 위해 View 클래스의 setOnLongClickListener() 메서드를 사용하여 리스너를 등록할 수 있습니다. 사용자가 해당 뷰를 길게 누르면 등록된 리스너가 호출되어 원하는 작업을 수행할 수 있습니다.
핵심: 롱클릭 = 1초 이상 누르는 이벤트
16.2.4 위젯이란?
위젯(Widget)은 사용자 인터페이스(UI)를 구성하는 요소로, 화면에 정보를 표시하거나 사용자와 상호 작용할 수 있는 기능을 제공합니다. 안드로이드 앱에서 위젯은 버튼, 텍스트뷰, 이미지뷰, 프로그레스바, 리사이클러뷰 등과 같은 다양한 요소를 포함합니다.
위젯은 앱의 사용자 인터페이스를 구성하고, 사용자가 앱과 상호 작용할 수 있도록 합니다. 예를 들어, 버튼을 클릭하여 작업을 수행하거나, 텍스트뷰에 정보를 표시하거나, 이미지뷰에 이미지를 로드하는 등의 기능을 수행할 수 있습니다.
안드로이드에서 위젯은 XML 레이아웃 파일에서 선언되거나, Java 또는 Kotlin 코드에서 동적으로 생성될 수 있습니다. 위젯은 앱의 사용자 경험을 향상시키고, 사용자가 앱과 상호 작용할 수 있는 중요한 요소입니다.
핵심: 위젯 = 화면에 정보 표시, 상호작용
마치며..
ViewModel에서부터 출발하여 바탕이 되는 모르는 용어와 개념들까지 모두 공부하니 좋은 경험이었습니다.
초반에 몰랐던 용어들을 정리해놓으니
후반에 가서는 그 용어들이 익숙해져서 공부하는 속도가 붙습니다.
애매하게 알고 있던 용어들을 공부해서 그런지 다른 자료들을 읽는데에 수월하더군요.
설명 퀄리티는 블로그 글이 훨씬 좋습니다. (정말 알고자 하면 발품을 파는 것이 중요하죠)
하지만 ChatGPT는 잘 모르는 문장의 뜻까지 물어보면 곧바로 대답을 하니 편리하다는 장점이 있습니다.
빠르게 개념을 짚어보고 싶다, 옆에 나쁘지 않은 과외 선생님이 있음 좋겠다, 한다면 추천할만한 공부방법이라 생각됩니다.
글이 2개 정도로 나뉠 줄 알았는데 긴 분량으로 3개가 되었습니다. (다 읽으실 분은 없으리라 생각됨)
파면 또 파지는게 공부.. 모르는 용어와 개념은 바닷가의 모래알보다 더 많습니다.
이젠 코드를 보러 가야겠습니다.
공부는 끝이 없네요.