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

2020. 4. 8. 07:09Dev & Tech/Android & iOS

반응형
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 개발의 기본을 다지는 데 도움이 되었기를 바랍니다!
긴 글 읽어주셔서 감사합니다.

끝.
반응형