본문 바로가기
Development/Android

[Android] Android Activity 생명주기와 실전 구현 방법 (기본)

by 은스타 2020. 4. 8.
반응형
Android Activity 생명주기와 실전 구현 방법 (기본)

Android Activity 생명주기와 실전 구현 방법 (기본)

Android 개발을 시작하면 반드시 알아야 하는 핵심 개념 중 하나가 바로 'Activity'입니다. Activity는 사용자와 직접 상호작용하는 화면을 담당하는 Android 앱 개발의 근간이 되는 요소입니다. 이 글에서는 초보 개발자도 쉽게 이해할 수 있도록 Activity의 기본 개념, 생명주기, 실전 구현 방법까지 상세히 알아보겠습니다. Android 공식 문서에서는 Activity를 "앱과 사용자가 상호작용할 수 있는 진입점이며, 앱이 UI를 그리는 창을 제공"한다고 정의합니다.

목차
1. Activity의 개념과 기본 구현
2. Activity 생명주기 완벽 이해
3. Activity 간 전환과 데이터 전달
4. Launch Mode와 상태 저장
5. 최신 Android 아키텍처 적용

#1. Activity의 개념과 기본 구현
Activity는 Android 앱에서 사용자와 상호작용하기 위한 단일 화면을 의미합니다. 앱은 보통 여러 개의 Activity로 구성되며, 각 Activity는 서로 다른 기능과 화면을 담당합니다.
1) Activity의 핵심 특징
android.app.Activity 클래스를 상속받아 구현합니다
② 최근에는 주로 androidx.appcompat.app.AppCompatActivity를 사용하여 하위 버전 호환성을 유지합니다
③ 각 Activity는 고유한 화면 레이아웃과 생명주기를 가집니다
④ 사용자 인터페이스와 비즈니스 로직을 함께 관리합니다
. . . . .
2) 기본 Activity 만들기
(1) Kotlin으로 작성한 기본 Activity
// Kotlin으로 작성한 기본 Activity
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // UI 초기화 작업
        val button = findViewById<Button>(R.id.button_start)
        button.setOnClickListener {
            // 버튼 클릭 처리
        }
    }
}
(2) AndroidManifest.xml에 등록하기
모든 Activity는 Android 시스템에 등록되어야 합니다. 이 작업은 AndroidManifest.xml 파일에서 이루어집니다:
<!-- AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <!-- 메인 Activity 선언 -->
        <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>
    </application>
</manifest>
android:exported="true"는 다른 앱에서 이 Activity를 시작할 수 있음을 의미하고, intent-filter의 MAIN 액션과 LAUNCHER 카테고리는 앱 런처에서 이 Activity를 시작 화면으로 표시합니다.

#2. Activity 생명주기 완벽 이해
Activity의 가장 중요한 특징 중 하나는 '생명주기(Lifecycle)'입니다. Activity는 생성되고, 사용자에게 보여지고, 다시 숨겨지며, 종료되기까지 여러 상태 변화를 겪게 됩니다.
1) Activity 생명주기 7가지 메서드
메서드 설명 주요 작업
onCreate() Activity가 처음 생성될 때 호출 레이아웃 설정, 뷰 초기화, 데이터 바인딩
onStart() 사용자에게 보여지기 직전 호출 UI 업데이트 준비, 애니메이션 준비
onResume() 사용자와 상호작용 가능 상태 실시간 데이터 업데이트, 카메라/센서 시작
onPause() 부분적으로 보이지 않을 때 호출 애니메이션 일시중지, 중요 데이터 저장
onStop() 완전히 가려질 때 호출 무거운 리소스 해제, DB 연결 해제
onRestart() 중지 후 다시 시작될 때 호출 일시중지된 작업 재개 준비
onDestroy() 완전히 종료되기 전 호출 모든 리소스 해제, 메모리 누수 방지
. . . . .
2) 생명주기 메서드 실전 코드
(1) onCreate() - UI 초기화
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // UI 초기화, 뷰 바인딩, 데이터 준비
    val button = findViewById<Button>(R.id.button_start)
    button.setOnClickListener {
        // 버튼 클릭 처리
    }
}
(2) onResume()과 onPause() - 리소스 관리
override fun onResume() {
    super.onResume()
    // 실시간 업데이트, 애니메이션 시작
    startLocationUpdates()
    resumeAnimations()
}

override fun onPause() {
    super.onPause()
    // 리소스 집약적 작업 일시 중지
    stopLocationUpdates()
    pauseAnimations()
    saveImportantData()
}
. . . . .
3) 주요 생명주기 이벤트 흐름
Activity 시작 - onCreate() → onStart() → onResume()
Activity 일시 중지 - onPause()
Activity 중지 - onPause() → onStop()
Activity 재시작 - onRestart() → onStart() → onResume()
Activity 종료 - onPause() → onStop() → onDestroy()

#3. Activity 간 전환과 데이터 전달
1) Intent로 새 Activity 시작하기
Android에서는 Intent를 사용하여 Activity 간 전환을 수행합니다:
// Kotlin에서 새 Activity 시작하기
val button = findViewById<Button>(R.id.button_start)
button.setOnClickListener {
    val intent = Intent(this, SecondActivity::class.java)
    startActivity(intent)
}
. . . . .
2) Intent로 데이터 전달하기
(1) 데이터 전송하는 Activity
// Kotlin으로 데이터 전달하기
val intent = Intent(this, SecondActivity::class.java).apply {
    putExtra("user_name", "John Doe")
    putExtra("user_age", 25)
    putExtra("is_premium", true)
}
startActivity(intent)
(2) 데이터 수신하는 Activity
// 전달받은 데이터 읽기
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_second)

    val userName = intent.getStringExtra("user_name") ?: "Unknown"
    val userAge = intent.getIntExtra("user_age", 0)
    val isPremium = intent.getBooleanExtra("is_premium", false)

    // 데이터 사용하기
    val textView = findViewById<TextView>(R.id.text_view)
    textView.text = "Name: $userName, Age: $userAge"
}
. . . . .
3) ActivityResultLauncher로 결과 받아오기
최신 Android에서는 ActivityResultLauncher를 사용하여 결과를 받아옵니다:
// 최신 방식 (ActivityResultLauncher 사용)
private val startForResult = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val data = result.data
        val returnedText = data?.getStringExtra("result_text") ?: ""
        Toast.makeText(this, "Returned: $returnedText", Toast.LENGTH_SHORT).show()
    }
}

// 버튼 클릭 시 Activity 시작
binding.buttonStartForResult.setOnClickListener {
    val intent = Intent(this, InputActivity::class.java)
    startForResult.launch(intent)
}

#4. Launch Mode와 상태 저장
1) Activity의 4가지 실행 모드
Launch Mode 설명 사용 예
standard 기본 모드, 항상 새 인스턴스 생성 일반적인 화면 전환
singleTop 최상단에 동일 Activity가 있으면 재사용 알림에서 Activity 시작
singleTask 태스크에 인스턴스 하나만 존재 홈 화면, 주요 진입점
singleInstance 독자적인 태스크에서 단독 실행 전화 앱 호출 화면
. . . . .
2) Activity 상태 저장 및 복원
화면 회전 등으로 Activity가 재생성될 때 상태를 유지하기 위한 방법:
// 상태 저장하기
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString("user_input", binding.editTextInput.text.toString())
    outState.putInt("counter", counter)
}

// 상태 복원하기
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    if (savedInstanceState != null) {
        val userInput = savedInstanceState.getString("user_input", "")
        counter = savedInstanceState.getInt("counter", 0)
    }
}

#5. 최신 Android 아키텍처 적용
1) ViewModel과 Activity
ViewModel을 사용하여 UI 데이터를 관리하고 화면 회전 시에도 데이터를 유지할 수 있습니다:
// ViewModel 정의
class MainViewModel : ViewModel() {
    private val _counter = MutableLiveData<Int>(0)
    val counter: LiveData<Int> = _counter

    fun incrementCounter() {
        _counter.value = (_counter.value ?: 0) + 1
    }
}

// Activity에서 ViewModel 사용
class MainActivity : AppCompatActivity() {
    private lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

        // LiveData 관찰
        viewModel.counter.observe(this) { count ->
            binding.textViewCounter.text = "Counter: $count"
        }
    }
}
. . . . .
2) 권한 처리하기
Android 6.0(API 23) 이상부터는 위험 권한을 실행 시간에 요청해야 합니다:
// 권한 확인 및 요청
private fun checkAndRequestPermission() {
    if (ContextCompat.checkSelfPermission(
        this, Manifest.permission.CAMERA
    ) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.CAMERA),
            CAMERA_PERMISSION_REQUEST_CODE
        )
    } else {
        startCamera()
    }
}

마무리
Activity는 Android 앱 개발의 핵심 구성 요소로서, 사용자 인터페이스와 상호작용을 담당합니다. 이 글에서는 Activity의 기본 개념부터 생명주기, 데이터 전달, 그리고 최신 아키텍처 적용까지 살펴보았습니다.
핵심 요약
Activity는 사용자와 상호작용하는 단일 화면을 담당합니다
생명주기 7가지 메서드를 이해하고 적절히 활용해야 합니다
③ Intent를 사용하여 Activity 간 전환과 데이터 전달을 수행합니다
④ Launch Mode를 활용하여 Activity 인스턴스 관리를 최적화합니다
ViewModel과 LiveData를 사용하여 최신 아키텍처를 적용합니다
Activity의 생명주기를 제대로 이해하고 관리하는 것은 안정적이고 효율적인 Android 앱을 만드는 기초입니다. 처음에는 복잡해 보일 수 있지만, 실제 프로젝트에서 반복적으로 사용하다 보면 자연스럽게 익숙해질 것입니다. 이 글이 Android 개발의 기본을 다지는 데 도움이 되었기를 바랍니다!
긴 글 읽어주셔서 감사합니다.

끝.
반응형