Activicy가 생성, 정지, 재생, 종료 등 여러 상태 간의 전환하기 위해 6가지 콜백으로 구성된 핵심 세트를 제공한다. Activity가 새로운 상태에 들어가면 시스템은 각 콜백을 호출한다.
💡 콜백(callback)이란? A가 어떤 특정한 동작을 한다면 A가 B에게 알려주는 것https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ko출처
최초로 Activiry가 생성 될 때 실행되는 메서드로 activity가 만들어질 때 단 한번만 호출 된다.
ex)데이터 바인딩, 뷰 바인딩,이전 상태 데이터 복구(savedInstanceState) 등
이 메서드가 실행을 완료가 되면 onStart()를 호출하게 된다.
Activiry가 onStop 이후 다시 시작되었을 때 실행하며 기능 자체는 onStart에서 해주는 일을 한다고 한다.
화면이 보여지기는 하지만 사용자와 상호작용을 하지 못하는 상태이다
onCreate()와 차이점이라면 onCreate()는 Activiry 실행될 때 딱 한번만 처리하고 onStart()는 onStop이 실행된 이후 다시 진행할 작업에 중점을 준다.
다시 앱으로 돌아올 때 무조건 호출 된다.예를 들면 앱 사용 중 전화가 와서 잠시 떠나거나 앱 상에서 카메라를 사용하여 카메라를 켠다는 상황에서 잠시 Activiry가 일시정지 되었다가 돌아오는 경우 해당한다.
Activiry가 다시 호출될 때 하면 되는 작업들을 onResume()에서 해준다.
Activity가 어떤 이벤트가 발생하여 화면의 일부가 가려 졌을 때 콜백을 호출하며 Activity가 일시중지가 된 상태이다.
onPause() 메서드는 아주 잠깐 실행되기 때문에 무거운 작업을 하면 안된다. 예를 들어 데이터 저장이나, 네트워크를 호출을 하는 작업이다.
화면 전부가 보이지 않을 때 호출이 되며 onPause() 메서드와 다른점은 화면이 일부 가리면 onPause()이고 화면이 완전히 가리면 onStop()이다. 그리고 onPause()에서 무거운 작업을 하면 안된다고 했는데 onStop()에서는 CPU를 비교적 많이 소모하는 작업을 수행할 수 있다.
Activity가 소멸 되기 전에 실행이 되며 onDestory()에서 생명주기가 종료됩니다.
먼저 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")
}
}
코드를 적고 빌드를 처음 하고 App이 실행 되었을 때 Logcat에서는 onCreate → onStart → onResume이 찍혔습니다.
공식문서 순서도에 따르면 지금 onCreate → onStart → onResume 거쳐 Activity running까지 들어온겁니다.
App이 완전히 사라졌기 때문에 onPause → onStop가 찍혔습니다.
순서도로 따라가 보면 Activity Running 상태에서 onPause → onStop순으로 가는걸 확인 하실 수 있습니다.
원래 순서도에 따르면 onRestart → onStart → onResume이 나옵니다. Log도 마찬가지로 onRestart → onStart → onResume 가 찍혀있습니다.
💡 onRestart()는 많이 사용되지 않는 LifeCycle이라 합니다.이론대로라면 일부가 가려졌을 때 니깐 onPause까지 찍혀야 하는데 onStop 까지 찍혔습니다.
왜 그런지 찾아보니 현재 액티비티가 그대로 실행되는 게 아니라 최근 화면의 리스트를 보여주는 화면이라고 합니다. 즉 이 화면에 의해 현재 실행되는 액티비티가 다 가려집니다.
Multitasking the Android Way
https://developer.android.com/guide/components/activities/recents
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% 가려지거나 완전히 멈춰질 때 조건이 됩니다.