Activity — 사용자 인터페이스가 있는 단일 화면을 나타내는 기본 Android 애플리케이션 구성 요소입니다. 시스템은 엄격한 생명 주기(onCreate, onResume, onDestroy 콜백)를 통해 화면을 관리합니다. 각 Activity는 AndroidManifest.xml에 선언되고 Intent를 통해 시작됩니다. Android의 역사에 대해 자세히 알아보려면 Google 공식 문서를 참조하세요.
주요 사항
Activity — 사용자 상호 작용을 위한 창을 제공하는 Android 애플리케이션의 핵심 구성 요소입니다. 각 Activity는 개별 화면(작업 목록, 로그인 양식, 사진 뷰어)을 관리합니다. Android 시스템은 요청 시 Activity를 생성하고 다른 애플리케이션이 메모리를 필요로 할 때 이를 소멸시킵니다.
Activity는 Android 1.0(2008)에서 처음 등장했으며 현재까지 인터페이스의 주요 구성 요소로 남아 있습니다. Google(2026)에 따르면 Google Play 앱의 98%가 최소 하나의 Activity를 포함합니다. 최신 아키텍처에서 Google은 하나의 Activity와 여러 Fragment를 권장하지만, 클래식 멀티 스크린 애플리케이션도 여전히 일반적인 방식입니다.
Activity stack(백 스택) — 탐색 기록을 저장하는 작업 스택입니다. 사용자가 "뒤로" 버튼을 누르면 현재 Activity가 소멸되고 이전 Activity가 복원됩니다. 시스템이 스택을 자동으로 관리하지만, 개발자는 launchMode와 Intent 플래그를 통해 동작을 제어할 수 있습니다.
Activity의 생명 주기는 화면이 생성부터 소멸까지 거치는 일련의 상태와 콜백입니다. Lifecycle을 이해하는 것은 매우 중요합니다: 잘못된 상태 처리는 메모리 누수, 데이터 손실 및 앱 충돌로 이어집니다.
Android 시스템은 엄격한 순서로 콜백을 호출합니다. 개발자는 리소스 초기화, 데이터 저장, 메모리 해제를 위해 필요한 메서드를 재정의합니다. 각 콜백에는 대응하는 쌍이 있습니다: onCreate ↔ onDestroy, onStart ↔ onStop, onResume ↔ onPause.
| 콜백 | 목적 | 개발자 작업 |
|---|---|---|
| onCreate | Activity 생성 시 호출 | UI 초기화, ViewModel 구독 |
| onStart | Activity가 표시됨 | 애니메이션, 카메라, GPS 시작 |
| onResume | Activity가 입력 포커스를 얻음 | 비디오, 타이머 재개 |
| onPause | Activity가 포커스를 잃음 | 임시 저장, 애니메이션 중지 |
| onStop | Activity가 다른 화면에 가려짐 | 무거운 리소스 해제 |
| onDestroy | Activity가 소멸됨 | 구독 정리, Closeable |
Activity에는 네 가지 상태가 있습니다: Running(onResume 활성), Paused(표시되지만 포커스 없음), Stopped(표시되지 않음), Destroyed(소멸됨). 시스템은 메모리 부족 시 Stopped 상태의 Activity를 종료할 수 있습니다 — 데이터는 onSaveInstanceState에 저장해야 합니다.
Kotlin 예제를 통해 Activity 생명 주기의 세 가지 주요 메서드를 살펴보겠습니다. onCreate — 진입점으로 한 번 호출됩니다. 여기서 setContentView를 통한 레이아웃 바인딩, RecyclerView 초기화, LiveData 구독이 이루어집니다. onStart — Activity가 사용자에게 표시됩니다. onResume — Activity가 포커스를 얻고 상호 작용할 준비가 됩니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.rv_items)
recyclerView.layoutManager = LinearLayoutManager(this)
loadItems()
}
override fun onStart() {
super.onStart()
startLocationUpdates()
}
override fun onResume() {
super.onResume()
resumeVideoPlayer()
}
}예제에서 onCreate는 RecyclerView를 초기화하고 데이터를 로드합니다. onStart는 위치 정보 업데이트를 시작합니다 — 화면이 표시될 때만 작동해야 하는 리소스입니다. onResume은 onPause에서 중지된 비디오를 재개합니다. 이러한 분리는 불필요한 백그라운드 작업을 방지합니다.
각 Activity는 AndroidManifest.xml 파일에 선언되어야 합니다. 등록하지 않으면 시스템이 화면을 찾지 못하고 ActivityNotFoundException을 발생시킵니다. 매니페스트에는 클래스 이름, 테마, 방향, launchMode 및 Intent 필터가 지정됩니다.
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/Theme.MyApp">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DetailActivity"
android:parentActivityName=".MainActivity" />
</application>exported 플래그는 다른 애플리케이션이 Activity를 시작할 수 있는지 여부를 결정합니다. 메인 화면의 경우 exported=true, 내부 화면의 경우 false입니다. parentActivityName 속성은 표준 "위로" 탐색(Up Navigation)을 활성화합니다.
Intent — 수행할 작업을 설명하는 객체입니다. Activity의 맥락에서 Intent는 데이터 전달과 함께 다른 화면을 시작하는 데 사용됩니다. Intent는 명시적(특정 클래스 지정)과 암시적(작업 지정, 시스템이 적절한 구성 요소 선택)일 수 있습니다.
// 명시적 Intent — 데이터와 함께 DetailActivity 시작
val intent = Intent(this, DetailActivity::class.java).apply {
putExtra("item_id", itemId)
putExtra("item_name", itemName)
}
startActivity(intent)
// DetailActivity에서 데이터 가져오기
val itemId = intent.getLongExtra("item_id", 0L)
val itemName = intent.getStringExtra("item_name") ?: ""시작된 Activity에서 결과를 받으려면 Activity Result API를 사용합니다. 이는 더 이상 사용되지 않는 startActivityForResult를 대체합니다. 새 API는 타입 세이프하고 선언적이며 Jetpack Compose와 함께 작동합니다.
private val getResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data?.getStringExtra("result_key")
}
}
fun openPicker() {
val intent = Intent(this, PickerActivity::class.java)
getResult.launch(intent)
}화면 회전 또는 구성 변경 시 Android는 Activity를 다시 생성합니다 — onDestroy와 onCreate를 순차적으로 호출합니다. 상태 저장 없이 사용자는 입력 데이터, 스크롤 위치 및 선택한 항목을 잃습니다. Android는 이 문제를 해결하기 위해 두 가지 메커니즘을 제공합니다: onSaveInstanceState와 ViewModel입니다.
onSaveInstanceState는 onDestroy가 호출되기 전에 Bundle에 간단한 데이터를 저장합니다. Jetpack의 ViewModel은 Activity 재생성을 견디고 메모리에 데이터를 저장하므로 복잡한 객체 및 네트워크 요청에 더 효율적입니다.
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ViewModel이 자동으로 데이터 저장
viewModel.items.observe(this) { items ->
updateAdapter(items)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("scroll_position", recyclerView.computeVerticalScrollOffset())
}
}Google의 최신 접근 방식은 하나의 Activity와 여러 Fragment를 사용하는 Single Activity 아키텍처입니다. 앱은 하나의 MainActivity를 사용하고 모든 탐색은 NavHostFragment를 통해 Navigation Component가 처리합니다. 장점: 중앙 집중식 탐색, 화면별 공유 ViewModel, 올바른 Deep Links 처리.
Jetpack Navigation Component는 백 스택 관리, 전환 애니메이션 및 인수 전달을 자동화합니다. NavHostFragment는 Activity 레이아웃에 배치되고 탐색 그래프(NavGraph)는 모든 화면과 그 사이의 연결을 설명합니다. 이 접근 방식은 Google이 새 프로젝트에 권장하며 Material Design 원칙을 따릅니다.
class MainActivity : AppCompatActivity() {
private val navController by lazy {
findViewById<NavHostFragment>(R.id.nav_host_fragment)
.navController
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// AppBar용 NavigationUI 설정
setupActionBarWithNavController(navController)
}
override fun onSupportNavigateUp() =
navController.navigateUp() || super.onSupportNavigateUp()
}자주 묻는 질문
Activity — 자체 생명 주기를 가진 완전한 애플리케이션 화면입니다. Fragment — Activity 내 UI의 일부로 Activity 재생성을 견디고 그 Lifecycle에 의존합니다. Activity는 필수, Fragment는 선택 사항입니다.
제한이 없습니다. 각 화면은 일반적으로 별도의 Activity로 표시됩니다. 간단한 앱은 하나면 충분하며, 멀티 스크린 앱의 경우 5~20개입니다. Google은 하나의 Activity와 여러 Fragment를 권장합니다.
launchMode는 작업 스택에서 Activity가 생성되는 방식을 결정합니다. 네 가지 모드: standard(새 인스턴스 생성), singleTop, singleTask(작업당 하나의 인스턴스), singleInstance(격리된 작업). 모드는 AndroidManifest.xml에서 설정됩니다.
Intent를 통해 — 프리미티브, 문자열, Parcelable 또는 Serializable을 포함할 수 있는 extras(putExtra)가 있는 객체입니다. 응답 통신에는 Activity Result API를 사용합니다 — startActivityForResult의 최신 타입 세이프 대체입니다.
Configuration Change — 구성 변경(화면 회전, 언어 변경, 키보드) 시 Activity 재생성입니다. 시스템은 onDestroy → onCreate를 호출합니다. 데이터 저장을 위해 onSaveInstanceState 또는 Jetpack의 ViewModel을 사용하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.