๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Android

[Android] Activity์˜ ์ƒ๋ช…์ฃผ๊ธฐ

interfacer_han 2024. 1. 23. 14:04

#1 Android Application์˜ ์‹œ์ž‘ (AndroidManifext.xml)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application ...>
        <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>

์šฐ๋ฆฌ๊ฐ€ ์•ฑ ์•„์ด์ฝ˜์„ ๋ˆ„๋ฅด๋ฉด, ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ์€ ํ•ด๋‹น ์•ฑ์˜ Launcher Activity๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค. AndroidManifext.xml์˜ ๋“ฑ๋ก๋œ ์•กํ‹ฐ๋น„ํ‹ฐ ์ค‘์—์„œ <category android:name="android.intent.category.LAUNCHER" /> ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” Activity๊ฐ€ Launcher Activity๋กœ ์„ค์ •๋œ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์กด์žฌํ•˜๋Š” Launcher Activity๊ฐ€ ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ์ž˜ ์•„๋Š” MainActivity๋‹ค.
 
์ด Launcher Activity๋ผ๋Š” ์ง„์ž…์ ์„ ํ†ตํ•ด ์•ฑ์ด ์‹คํ–‰๋˜๋ฉด, ๋น„๋กœ์†Œ ์•กํ‹ฐ๋น„ํ‹ฐ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ์‹œ์ž‘๋œ๋‹ค.
 

#2 Activity LifeCycle

#2-1 ์ƒ๋ช…์ฃผ๊ธฐ ํ๋ฆ„๋„

https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ko

'Activity launched'๊ฐ€ #1์—์„œ ๋งํ•œ ์•ฑ์˜ ์ง„์ž…์ ์ด๋‹ค. ์ง„์ž…์  ์ดํ›„์—๋Š” ์—ฌ๋Ÿฌ ์ƒํƒœ(State)๊ฐ€ ์žˆ์œผ๋ฉฐ, Activity๋ฅผ ์ด State๋“ค์„ ์ด๋ฆฌ์ €๋ฆฌ ๋Œ์•„๋‹ค๋‹Œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒํƒœ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๋“ค์€ ์ฝœ๋ฐฑ(Callback) ํ•จ์ˆ˜๋‹ค. Android ์‹œ์Šคํ…œ์— ์˜ํ•ด ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘์ ์œผ๋กœ onCreate() ๋“ฑ์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉฐ, ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•ด์„œ ์„ค๊ณ„๋งŒ ํ•ด๋‘”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ์€ ์•ฑ์˜ ์ƒ๋ช…์ฃผ๊ธฐ์— ๋”ฐ๋ผ ํ•„์š”ํ•œ ์‹œ์ ์— ๊ฐœ๋ฐœ์ž์— ์˜ํ•ด ์„ค๊ฒŒ๋œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
 

#2-2 onCreate()

์ƒ๋ช…์ฃผ๊ธฐ์—์„œ ๋ฐ˜๋“œ์‹œ ๋‹จ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  Activity์˜ ๊ทผ๊ฐ„์„ ์งœ๋Š” ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ํ•จ์ˆ˜๋“ค๊ณผ ๋‹ฌ๋ฆฌ ์˜ค๋ฒ„๋ผ์ด๋“œ๊ฐ€ ๊ฐ•์ œ๋œ๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ ์ŠคํŠœ๋””์˜ค์—์„œ ๋นˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ์žˆ๋Š” MainActivity์— onCreate()๊ฐ€ ์ด๋ฏธ ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ๊ทธ๊ฒƒ์ด ๊ฐ•์ œ ์‚ฌํ•ญ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
 

#2-3 onStart()

์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๊ธฐ ์ง์ „์— ํ˜ธ์ถœ๋œ๋‹ค. ์ด ์ƒํƒœ(State)์—์„œ Activity๋Š” ์Šค๋งˆํŠธํฐ์˜ 'ํ™”๋ฉด(Foreground)'์— ๋„์›Œ์งˆ ๊ฒƒ์„ ๋Œ€๋น„ํ•ด ์Šค๋งˆํŠธํฐ ์‚ฌ์šฉ์ž์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ์ค€๋น„๋ฅผ ํ•œ๋‹ค. UI๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ์ด ๋‹จ๊ณ„์ด๋‹ค.
 

#2-4 onResume()

Activity๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ์ƒํƒœ๋‹ค. ์ฆ‰, ์•ฑ์˜ ํ™”๋ฉด์ด ์‚ฌ์šฉ์ž์˜ ๋ˆˆ์— ๋ณด์ด๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์ˆœ๊ฐ„์ด๋‹ค. ์ด ์ƒํƒœ๋ฅผ 'Activity running'์ด๋ผ๊ณ  ํ•œ๋‹ค. onResume()์€ onStart() ํ˜น์€ onPause()์˜ ๋‹ค์Œ ์ƒํƒœ๋‹ค. Activity๊ฐ€ ์‹คํ–‰ ์ค‘์ผ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ด๋ฏ€๋กœ, ๋งŽ์€ ์‹ ๊ฒฝ์„ ์จ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, onPause() ๋‹ค์Œ์œผ๋กœ ์‹คํ–‰๋  ๋•Œ๋ฅผ ๋Œ€๋น„ํ•ด ์„œ๋ฒ„์™€์˜ (์žฌ)์—ฐ๊ฒฐํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์จ ๋„ฃ๋Š” ์‹์ด๋‹ค.
 

#2-5 onPause()

์ผ์‹œ์ค‘์ง€ ์ƒํƒœ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ํ™ˆ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €๊ฑฐ๋‚˜, ํ˜น์€ ๊ฐ‘์ž๊ธฐ ์ „ํ™”๊ฐ€ ์™€์„œ ์ „ํ™” ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜๋˜๋Š” ๋“ฑ 'ํ™”๋ฉด ๋ฐ–(Background)'์œผ๋กœ Activity๊ฐ€ ํŠ•๊ฒจ์ ธ๋‚˜๊ฐ€๋ฉด onPause()๊ฐ€ ์‹คํ–‰๋œ๋‹ค. onPause() ์ƒํƒœ์—์„  ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์ด Background์— ์žˆ์„ ๋•Œ ์‹คํ–‰๋˜์–ด์„  ์•ˆ ๋˜๋Š” ๋™์ž‘์„ ๋ง‰์•„์•ผ ํ•œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค Activity๋ฅผ ํ™”๋ฉด ๋ฐ–์œผ๋กœ ์น˜์šฐ๊ณ  ๋‹ค๋ฅธ ์ผ์„ ํ•˜๊ณ  ์žˆ์Œ์—๋„, ํ•ด๋‹น Activity๊ฐ€ ์˜ˆ๋ฅผ ๋“ค์–ด, ์„œ๋ฒ„์™€ ํ†ต์‹ ์„ ํ•œ๋‹ค๋ฉด ๋งŽ์€ ์ž์›์ด ๋‚ญ๋น„๋  ๊ฒƒ์ด๋‹ค.
 
onPause()์ผ ๋•Œ, ๋‹ค์‹œ Activity๋ฅผ 'ํ™”๋ฉด(Foreground)'๋กœ ๋ถˆ๋Ÿฌ๋“ค์ด๋ฉด onResume()์ด ์‹คํ–‰๋œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ํ™ˆํ™”๋ฉด์—์„œ ๋‹ค์‹œ ์•ฑ์„ ์‹คํ–‰์‹œํ‚ค๊ฑฐ๋‚˜ ์ „ํ™”๊ฐ€ ๋๋‚˜์„œ ์Šค๋งˆํŠธํฐ ํ™”๋ฉด์ด ์›๋ž˜ ํ•˜๋˜ ์•ฑ์œผ๋กœ ์ž๋™ ์ „ํ™˜๋œ ๊ฒฝ์šฐ๋‹ค.
 

#2-6 onStop()

onPause() ์ƒํƒœ์—์„œ ์•ฑ์ด ์žฅ๊ธฐ๊ฐ„ onResume()๋˜์ง€ ์•Š์œผ๋ฉด ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ์€ ํ•ด๋‹น Activity๋ฅผ onStop() ์ƒํƒœ๋กœ ๋ณด๋‚ธ๋‹ค. ์ด ๊ฒฝ์šฐ, Activity์˜ ์ธ์Šคํ„ด์Šค๋Š” ์—ฌ์ „ํžˆ ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ•˜์ง€๋งŒ UI ํ™”๋ฉด ๊ตฌ์„ฑ์€ ํŒŒ๊ดด๋œ๋‹ค.
 

#2-7 onRestart()

onStop() ์ƒํƒœ์ผ๋•Œ ์‚ฌ์šฉ์ž๊ฐ€ Activity๋ฅผ 'ํ™”๋ฉด ์•ˆ(Foreground)'์œผ๋กœ ๋Œ์–ด๋‹ค๋†“์œผ๋ฉด ์‹คํ–‰๋œ๋‹ค. UI๋Š” ์ด๋ฏธ ์†Œ์‹ค๋œ ์ƒํƒœ์ด๋ฏ€๋กœ, onRestart()์™€ onStart()๋ฅผ ๊ฑฐ์ณ UI๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค๊ณ , onResume()์—์„œ ๋‹ค์‹œ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•ด๋‹น UI๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.
 

#2-8 onDestroy()

'์•ฑ ์ข…๋ฃŒํ•˜๊ธฐ' ๋ฒ„ํŠผ์„ ๋งŒ๋“œ๋Š” ๋“ฑ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์˜๋„์ ์œผ๋กœ Activity๋ฅผ ํŒŒ๊ดดํ•˜๋Š” ๋ช…์‹œ์  ์ฝ”๋“œ๋ฅผ ์งฐ๊ฑฐ๋‚˜, ํ™”๋ฉด ํšŒ์ „(ํ•ด๋‹น ๋งํฌ์˜ #1-2 ์ฐธ์กฐ)์ด๋‚˜ ์–ธ์–ด ๋ณ€๊ฒฝ๊ณผ ๊ฐ™์€ ํ™˜๊ฒฝ์˜ ๋ณ€ํ™”(Configuration Change)๊ฐ€ ์ƒ๊ธฐ๋ฉด ํ˜ธ์ถœ๋˜๋Š” ์ƒํƒœ๋‹ค. ํ›„์ž์˜ ๊ฒฝ์šฐ์—๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ์€ ๊ณง๋ฐ”๋กœ onCreate() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 
 

#3 ์•กํ‹ฐ๋น„ํ‹ฐ ์ƒ๋ช…์ฃผ๊ธฐ ์‚ดํŽด๋ณด๊ธฐ์šฉ ์•ฑ

#3-1 MainActivity.kt

// package com.example.activitylifecyclelogger

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        Log.i("interfacer_han", "MainActivity.onCreate()")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val switchActivityButton = findViewById<Button>(R.id.switchActivityButton)
        switchActivityButton.setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java)
            /* FLAG_ACTIVITY_REORDER_TO_FRONT ํ”Œ๋ž˜๊ทธ๋Š” ํ˜ธ์ถœํ•˜๋ ค๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์ด๋ฏธ ์Šคํƒ์— ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ,
             * ํ•ด๋‹น ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ์Šคํƒ์˜ ๋งจ ์œ„๋กœ ์ด๋™์‹œํ‚ค๊ณ  ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋„๋ก ํ•จ.
             * ์ด ํ”Œ๋ž˜๊ทธ๊ฐ€ ์—†์œผ๋ฉด, Activity๋ฅผ ์ „ํ™˜ํ•  ๋•Œ๋งˆ๋‹ค onCreate()๋จ.
             */
            intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
            startActivity(intent)
        }
    }

    override fun onStart() {
        Log.i("interfacer_han", "MainActivity.onStart()")
        super.onStart()
    }

    override fun onResume() {
        Log.i("interfacer_han", "MainActivity.onResume()")
        super.onResume()
    }

    override fun onPause() {
        Log.i("interfacer_han", "MainActivity.onPause()")
        super.onPause()
    }

    override fun onStop() {
        Log.i("interfacer_han", "MainActivity.onStop()")
        super.onStop()
    }

    override fun onRestart() {
        Log.i("interfacer_han", "MainActivity.onRestart()")
        super.onRestart()
    }

    override fun onDestroy() {
        Log.i("interfacer_han", "MainActivity.onDestroy()")
        super.onDestroy()
    }
}

๊ธฐ๋ณธ์ ์œผ๋กœ ์กด์žฌํ•˜๋Š” onCreate() ์™ธ์˜ ๋‹ค๋ฅธ State์— ํ•ด๋‹นํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋“ค์„ ์ „๋ถ€ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ณ  Log๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณธ๋‹ค.
 

#3-2 SecondActivity.kt

#3-1๊ณผ ๊ฑฐ์˜ ๊ฐ™์Œ (์ƒ๋žต)

MainActivity์—์„œ ์ „ํ™˜๋  ์•กํ‹ฐ๋น„ํ‹ฐ๋‹ค. ํ•ด๋‹น ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ MainActivity๋กœ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
 

#3-3 ๋กœ๊ทธ ํ™•์ธ - ์•กํ‹ฐ๋น„ํ‹ฐ ์ „ํ™˜

1. ์‹œ์ž‘ ํ™”๋ฉด (MainActivity)
     MainActivity.onCreate()
     MainActivity.onStart()
     MainActivity.onResume()

2. SecondActivity๋กœ ์ „ํ™˜
     MainActivity.onPause()
     SecondActivity.onCreate()
     SecondActivity.onStart()
     SecondActivity.onResume()
     MainActivity.onStop()
 
3. ๋‹ค์‹œ MainActivity๋กœ ์ „ํ™˜
     SecondActivity.onPause()
     MainActivity.onRestart()
     MainActivity.onStart()
     MainActivity.onResume()
     SecondActivity.onStop()
 

#3-4 ๋กœ๊ทธ ํ™•์ธ - ์•กํ‹ฐ๋น„ํ‹ฐ ํšŒ์ „

1. ์‹œ์ž‘ ํ™”๋ฉด (MainActivity)
    MainActivity.onCreate()
    MainActivity.onStart()
    MainActivity.onResume()
 
2. ์‹œ์ž‘ ํ™”๋ฉด์—์„œ 90๋„ ํšŒ์ „
     MainActivity.onPause()
     MainActivity.onStop()
     MainActivity.onDestroy()
     MainActivity.onCreate()
     MainActivity.onStart()
     MainActivity.onResume()
 
3. (2)์—์„œ 180๋„ ํšŒ์ „
๋กœ๊ทธ ๋ฐœ์ƒ๋˜์ง€ ์•Š์Œ. ๊ฐ€๋กœ์™€ ์„ธ๋กœ์˜ ๋„ˆ๋น„๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ํšŒ์ „์ด๊ธฐ ๋•Œ๋ฌธ์— ํ™˜๊ฒฝ ๋ณ€ํ™”๋Š” ์—†๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋”ฐ๋ผ์„œ onDestroy()๋„ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
 

#4 ์š”์•ฝ

์•กํ‹ฐ๋น„ํ‹ฐ ์ƒ๋ช…์ฃผ๊ธฐ๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ์˜ ํ—Œ๋ฒ•์ด๋‹ค.
 

#5 ์™„์„ฑ๋œ ์•ฑ

https://github.com/Kanmanemone/android-practice/tree/master/lifecycle/ActivityLifecycleLogger