<Android>안드로이드 생명주기

진섭·2022년 4월 18일
0
post-thumbnail
post-custom-banner

📌생명주기(Life Cycle)란?

Activicy가 생성, 정지, 재생, 종료 등 여러 상태 간의 전환하기 위해 6가지 콜백으로 구성된 핵심 세트를 제공한다. Activity가 새로운 상태에 들어가면 시스템은 각 콜백을 호출한다.

💡 콜백(callback)이란? A가 어떤 특정한 동작을 한다면 A가 B에게 알려주는 것

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

📌onCreate()

최초로 Activiry가 생성 될 때 실행되는 메서드로 activity가 만들어질 때 단 한번만 호출 된다.

ex)데이터 바인딩, 뷰 바인딩,이전 상태 데이터 복구(savedInstanceState) 등

이 메서드가 실행을 완료가 되면 onStart()를 호출하게 된다.

📌onRestart

Activiry가 onStop 이후 다시 시작되었을 때 실행하며 기능 자체는 onStart에서 해주는 일을 한다고 한다.

📌onStart()

화면이 보여지기는 하지만 사용자와 상호작용을 하지 못하는 상태이다

onCreate()와 차이점이라면 onCreate()는 Activiry 실행될 때 딱 한번만 처리하고 onStart()는 onStop이 실행된 이후 다시 진행할 작업에 중점을 준다.

📌onResume()

다시 앱으로 돌아올 때 무조건 호출 된다.예를 들면 앱 사용 중 전화가 와서 잠시 떠나거나 앱 상에서 카메라를 사용하여 카메라를 켠다는 상황에서 잠시 Activiry가 일시정지 되었다가 돌아오는 경우 해당한다.

Activiry가 다시 호출될 때 하면 되는 작업들을 onResume()에서 해준다.

📌onPause()

Activity가 어떤 이벤트가 발생하여 화면의 일부가 가려 졌을 때 콜백을 호출하며 Activity가 일시중지가 된 상태이다.

onPause() 메서드는 아주 잠깐 실행되기 때문에 무거운 작업을 하면 안된다. 예를 들어 데이터 저장이나, 네트워크를 호출을 하는 작업이다.

📌onStop()

화면 전부가 보이지 않을 때 호출이 되며 onPause() 메서드와 다른점은 화면이 일부 가리면 onPause()이고 화면이 완전히 가리면 onStop()이다. 그리고 onPause()에서 무거운 작업을 하면 안된다고 했는데 onStop()에서는 CPU를 비교적 많이 소모하는 작업을 수행할 수 있다.

📌onDestory()

Activity가 소멸 되기 전에 실행이 되며 onDestory()에서 생명주기가 종료됩니다.

📌생명주기 Log 찍어보기

먼저 MainActiviy에 다음과 같이 Log.d를 찍어 주었습니다.

package com.example.lifecycle

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {
    //최초로 Activiry가 생성 될 때 실행되는 메서드 단 한번만 호출 된다.
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("life_cycle", "onCreate")
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("life_cycle", "onRestart")
    }

    //Ctrl + o 로 매서드를 만들 수 있다.
    // onCreate() 이후에 실행 된다 Activity가 실행되며 사용자가 앱과 상호 작용을 준비 한다.
    override fun onStart() {
        super.onStart()
        Log.d("life_cycle", "onStart")
    }

    //    다시 앱으로 돌아올 떄 호출 된다.
    override fun onResume() {
        super.onResume()
        Log.d("life_cycle", "onResume")
    }

    //    화면의 일부가 가려 졌을 때
    override fun onPause() {
        super.onPause()
        Log.d("life_cycle", "onPause")
    }

    //    화면 전부가 보이지 않을 때때
    override fun onStop() {
        super.onStop()
        Log.d("life_cycle", "onStop")
    }

    //    완전히 소멸 되기전에 실행
    override fun onDestroy() {
        super.onDestroy()
        Log.d("life_cycle", "onDestroy")
    }
}

📌 1. App을 처음 실행하였을 때

코드를 적고 빌드를 처음 하고 App이 실행 되었을 때 Logcat에서는 onCreate → onStart → onResume이 찍혔습니다.

공식문서 순서도에 따르면 지금 onCreate → onStart → onResume 거쳐 Activity running까지 들어온겁니다.

📌 2. App을 Home버튼을 눌러 완전히 닫았을 때

App이 완전히 사라졌기 때문에 onPause → onStop가 찍혔습니다.

순서도로 따라가 보면 Activity Running 상태에서 onPause → onStop순으로 가는걸 확인 하실 수 있습니다.

📌 3. 다시 App으로 돌아갔을 때 Log

원래 순서도에 따르면 onRestart → onStart → onResume이 나옵니다. Log도 마찬가지로 onRestart → onStart → onResume 가 찍혀있습니다.

💡 onRestart()는 많이 사용되지 않는 LifeCycle이라 합니다.

📌 4. App의 상태를 완전히 닫는게 아니라 멀티태스킹 버튼을 클릭 했을 때 Log

이론대로라면 일부가 가려졌을 때 니깐 onPause까지 찍혀야 하는데 onStop 까지 찍혔습니다.

왜 그런지 찾아보니 현재 액티비티가 그대로 실행되는 게 아니라 최근 화면의 리스트를 보여주는 화면이라고 합니다. 즉 이 화면에 의해 현재 실행되는 액티비티가 다 가려집니다.

Multitasking the Android Way
https://developer.android.com/guide/components/activities/recents

📌 5. onPause 예시

onPause를 찍히게 하기 위해 홍드로이드라는 유튜버분이 실습 영상을 통해 실습을 하였습니다.

onPause 실습

안드로이드 앱 만들기 #45 생명주기 ( Life Cycle ) - 쉽게 앱 만드는 방법 (현직 개발자 설명) , android studio easy tutorial

<MainActivity 코드>

package com.example.lifecycle

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.example.lifecycle.databinding.ActivityMainBinding
import com.example.lifecycle.databinding.ActivitySecondBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    //최초로 Activiry가 생성 될 때 실행되는 메서드 단 한번만 호출 된다.
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
setContentView(view)
        Log.d("life_cycle", "onCreate")

        //btnMove를 클릭을 할때 동작
        binding.btnMove.setOnClickListener{
//            MainActivity -> subActivity 이동
            startActivity(Intent(this@MainActivity, SecondActivity::class.java))
}

}

    override fun onRestart() {
        super.onRestart()
        Log.d("life_cycle", "onRestart")
    }

    //Ctrl + o 로 매서드를 만들 수 있다.
    // onCreate() 이후에 실행 된다 Activity가 실행되며 사용자가 앱과 상호 작용을 준비 한다.
    override fun onStart() {
        super.onStart()
        Log.d("life_cycle", "onStart")
    }

    //    다시 앱으로 돌아올 떄 호출 된다.
    override fun onResume() {
        super.onResume()
        Log.d("life_cycle", "onResume")
    }

    //    화면의 일부가 가려 졌을 때
    override fun onPause() {
        super.onPause()
        Log.d("life_cycle", "onPause")
    }

    //    화면 전부가 보이지 않을 때때
    override fun onStop() {
        super.onStop()
        Log.d("life_cycle", "onStop")
    }

    //    완전히 소멸 되기전에 실행
    override fun onDestroy() {
        super.onDestroy()
        Log.d("life_cycle", "onDestroy")
    }
}

<SecondActivity 코드>

package com.example.lifecycle

import android.app.Activity

import android.os.Bundle

class SecondActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
    }
}

<build.gradle 뷰바인딩>

android {
        ...
        viewBinding {
            enabled = true
        }
    }

<activity_main 코드>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_move"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Main 버튼"/>

</androidx.constraintlayout.widget.ConstraintLayout>

<activity_second 코드>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <Button
        android:text="Sub 버튼"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

<Manifest.xml 코드>

        <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=".SecondActivity"   // SecondActivity activity 추가해주기
            android:theme="@android:style/Theme.Translucent"/>  // 투명 테마 
    </application>

</manifest>

자 인제 준비가 다 되었으니 빌드를 해보면 다음과 같이 나옵니다.

지금 이 상태는 mainActivity에서 SecondActivity로 이동을 한 상태이며 MainActivity 위에 SecondActivity가 겹쳐 있는 상태입니다.

그렇게 때문에 onStop까지 갈 수 있는 조건이 안됩니다.

onStop에 가기 위해서는 화면이 100% 가려지거나 완전히 멈춰질 때 조건이 됩니다.

post-custom-banner

0개의 댓글