HFAD 메모

timothy jeong·2021년 11월 29일
0

Android with Kotlin

목록 보기
53/69

액티비티에 대해서

액티비티의 상속체계

Context : application environment 의 전역 정보에 대한 접근 권한을 준다.
ContextWrapper : proxy implementation for the Context
ContextThemeWrapper : 요런것도 있더라
Activity : 액티비티 라이프 사이클 함수와, setContentView(), findViewById() 등을 구현한 클래스이다.
androidx.core.app.ComponentActivity : 요런것도 있더라
ComponentActivity: 요런것도 있더라
FragmentActivity : 요런것도 있더라
AppCompactActivity : jetpack 라이브러리에 있는 클래스로 호환성 문제를 해결해준다.

MainActivity : 개발자가 실제로 조작하는 액티비티

super.onCreate()

onCreate 뿐만 아니라 다른 액티비티 라이프 사이클 함수를 호출했을 때 super.OnCreate(savedInstanceState) 과 같은 것들이 있다. 위의 상속 체계를 보면, Activity 클래스에서 라이프 사이클 함수가 구현되어 있다고 했고, 이는 Activity 의 라이프 사이클 함수를 호출하는 역할을 한다.

상위 클래스(superClass) 에 정의되어 있는 함수를 우선 호출함으로써 이 함수가 제대로 동작하도록 한다.

스마트폰을 가로 방향으로 돌렸을때 레이아웃이 초기화되는 이유 :

앱을 실행할때 (즉, MainActivity 가 실행될 때) device configuration 을 고려하기 때문이다. 즉, 스마트폰의 물리적인 설정값(스크린 사이즈, 스크린 시작 방향 등) 과 user locale 을 고려한다는 것이다. 스마트폰을 가로 방향으로 돌린다면 혹은 user locale 이 변경되면 현재 액티비티를 destroy 하고 변경된 device configuration 정보를 참조하여 onCreate 를 다시 호출한다.

state 저장하고 복원하기

핵심은 bundle 이다. bundle 은 액티비티 인스턴스 사이에 교환되는 정보를 가지고 있는 객체이며 key, value 형태로 된 정보를 갖는다.

onSaveInstanceState() 함수에서 bundle 에 필요한 값들을 넣어두면 onCreate() 함수에서 꺼내서 사용할 수 있다. 이 함수는 액티비티가 destroy 되기 전에 호출된다.

만약 액티비티가 처음으로 만들어지는 상황에서는 Bundle? 객체가 null 이지만, 다시 create 가 호출되는 상황에서는 null 이 아니다. 따라서 onCreate 에서는 아래와 같이 분기를 나눠서 처리를 해줘야한다.

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    if (savedInstanceState != null) {
        savedInstanceState.get 뭐시기뭐시기
    }
}

화면을 돌리고도 state 를 저장할 수 있다. bundle.putInt(key, value) 로 넣고, bundle.getInt(key) 로 뺄 수 있다.

액티비티 라이프 싸이클 리마인드하기

onCreate()

액티비티가 실행되자마자 실행되는 함수이다. 일반적인 액티비티 셋업은 모두 이 함수에서 끝마친다.

active state (running state)

액티비티가 스크린의 포어그라운드에 있으며, 포커스된 상태이며, 유저가 액티비티와 상호작용을 할 수 있는 상태를 의미한다.

onDestroy()

액티비티가 destroy 되기 전에 호출되는 함수이다. destory 될 수 있는 경우는 여러가지가 있는데, 개발자가 finish() 함수를 호출하여 손수 액티비티를 끝내거나, devic configuration 이 변경되거나, 안드로이드 시스템이 메모리 공간 확보를 위해 액티비티를 없애기로 결정한 순간이다.

만약 스마트폰의 메모리 공간이 대단히 부족한 상황에서는 onDestroy() 함수가 호출되지 못할 수도 있다.

onCreate() -> onDestroy() 아주 직관적인 라이프 사이클이다. 하지만 안드로이드 앱은 갑자기 전화가 올때 백그라운드로 들어가는 등의 상황을 맞게 된다.

onStop()

onStop() 함수는 액티비티가 다른 액티비티에 의해 스크린에서 사라졌을때 호출된다. 유저의 시야에서 사라졌음에도 불구하고 해당 액티비티는 백그라운드에 여전히 존재하며, 모든 state 들이 보존되어 있다. 이때 액티비티가 stopped 상태에 있다고 한다.

onRestart()

액티비티가 스크린에서 사라진뒤, 다시 스크린으로 나오려고 할때 호출되는 함수이다. stopped 상태의 액티비티가 다시 스크린으로 나올떄는 onCreate() 가 아니라 onRestart() 가 호출되는 것이다.

onStart()

이전에 액티비티가 어떤 상태였든간에 액티비티가 스크린에 나와서 유저에게 보일때 호출되는 함수이다. onCreate() 이후에, 그리고 onRestart() 이후에 호출된다.

onPuase()

앱을 이용하다가 갑자기 구글 어시스턴트가 켜지는 순간에는 기존에 이용하던 액티비티를 이용할 수 있는 상황이 아니다. 그러므로 active state 라고 할 수 없다. 이러한 상황을 puased state 라고 하며, 액티비티가 유저의 스크린에 보이지만 상호작용은 할 수 없는 상활을 말한다.

Puased state 역시 stop state 와 똑같이 모든 액티비티 state 들이 저장된 상태이다.

onResume()

puased 상태에서 다시 active 상태로 돌아갈때는 어떤 함수가 호출되어야 할까? onCreate 는 당연히 아니고, onRestart 는 다시 스크린에 나타나는 상황에서 호출되는 함수인데...puased 상태에서는 focus 만 잃은거지 계속 스크린에 보이는 상태였음으로 해당되지 않는다. 이때는 onResume 함수가 호출된다.

onResume 함수는 액티비티가 유저와 상호작용을 하기 바로 직전에 호출된다.

종합

지금까지 정리된 바에 의하면 앱이 시작되고 onCreate() 를 통해 액티비티 셋업을 하고
onStart() 를 통해 스크린에 액티비티 레이아웃이 나타난다.
그리고 onResume() 이 호출되고 유저가 액티비티와 상호작용을 할 수 있게된다.
이상을 모두 마치고 나서야 액티비티는 active 상태가 된다.

이 때 액티비티가 포커스를 잃으면 onPuse() 가, 다시 포커스를 되찾으면 onResume()
만약 액티비티가 백그라운드로 가야하는 상황에서는 onStop() 이, 다시 스크린에 나타난다면 onStart(), onResume() 이 호출된다.

그리고 앱이 destroy 되면 onDestroy 가 호출된다.

프레그먼트에 대해서

onCreateView() 메서드를 구현하는건 선택사항이지만, 안드로이드가 프레그먼트의 레이아웃에 접근할때 호출하는 메서드이며, 프레그먼트가 레이아웃을 보여주는 역할을 맡았다면 반드시 구현해야 한다.

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return super.onCreateView(inflater, container, savedInstanceState)
    }

LayoutInflater 는 레이아웃 xml 파일을 객체로 바꿔주는 역할을 한다.
ViewGroup? 은 프레그먼트를 보여주는 액티비티의 레이아웃을 의미하고, Bundle? 은 액티비티의 onCreate 함수에 파라미터로 넘어가는 Bundle 과 비슷하게 작동하여 저장된 fragment 의 state를 이용할 때 사용한다.

fragment 를 표시할 곳에 FragmentContainerView 를 배치하는 것이 일반적이다.

profile
개발자

0개의 댓글