AppCompatActivity 파헤치기

hongbeom
6 min readJul 17, 2021

AppCompatAcitivity는 어떤 동작을 가지는지 알아봅니다.

AppCompatActivity

우리는 일반적으로 액티비티를 선언할 때, Activity를 상속받아서 작성하곤 합니다. 그런데 사실, Activity는 종류가 여러가지 존재합니다. 아래 그림과 같은 상속 구조를 가지며, 최종적으로 AppCompatActivity까지 자식을 가지고 있습니다. 본 글에서는 가장 하위 클래스인 AppCompatActivity에 대해 알아보고자 합니다. 일단 Compat이라는 이름부터 호환성을 의미하는 compatibility의 줄임말임을 유추해볼 수 있는데요. 어떤 호환성을 의미하는 것이고 어떻게 지원해준다는 걸까요?

다양한 Activity들

Android 3.0(API Level 11)부터는 기본적으로 Activity들은 Appbar로 모두 ActionBar를 가지고 있습니다. 이런 특정 버전부터 지원되는 ActionBar를 해당 버전 이하의 버전에도 적용할 수 있도록 지원해주는 Activity가 바로 AppCompatActivity입니다.

AppCompatActivity는 크게 다음과 같은 3가지 특징을 가지고 있습니다.

⚠️ 이 클래스를 확장하는 모든 액티비티는 AppCompat 또는 해당 테마를 확장하는 테마를 사용해야 합니다.

Method 살펴보기

이제 몇 가지 핵심 메소드들을 살펴보겠습니다.

initDelegate()

saveState 이벤트가 발생할때 필드로 가지고 있는 AppCompatDelegate의 (getDelegate로 불러옴) onSaveInstanceState 메소드를 호출하여 AppCompatDelegate에 상태를 저장하는 로직이 작성되어 있으며 AppCompatDelegate를 초기화하는 메소드 입니다.

그리고 Context에 접근할 수 있을 때의 콜백을 작성하는데, 델리게이트를 사용하여 installViewFactory 메소드를 호출하여 라이프사이클 등등을 초기화합니다.

setSupportActionBar(@Nullable Toolbar toolbar)

  • window에 대한 action bar를 지정합니다.
  • 전통적인 window decorView에 있는 action bar의 toolbar 처럼 사용할 수 있습니다.
  • 액티비티의 window에서 toolbar를 사용하려면 애플리케이션에서 해당 window feature를 요청하지 않아야합니다. (Window.FEATURE_ACTION_BAR)

실제로 getDelegate()를 통해 접근하는 AppCompatDelegateImplsetSupportActionBar의 구현은 다음과 같습니다.

dispatchKeyEvent(KeyEvent event)

액션바가 현재 처리 중인 window 보다 우선순위가 높은 메뉴 키에 응답하여 메뉴를 열도록 해줍니다.

onMenuItemSelected(int featureId, @NonNull android.view.MenuItem item)

메뉴 아이템이 선택될 때 호출되는 메소드입니다.

위 로직을 통해 기본적으로 home 아이템이 선택되면 onSupportNavigateUp이 호출됩니다.

onSupportNavigateUp()

사용자가 우리의 애플리케이션 액티비티 계층에서 액션바의 뒤로가기(Up)를 선택할 때마다 이 메소드를 호출합니다.

상위 항목이 이 액티비티의 매니페스트에 지정된 경우 또는 해당 액티비티에 대한 액티비티 별칭이 지정된 경우 기본 뒤로가기(Up) 탐색이 자동으로 처리됩니다

아래의 getSupportParentActivityIntent 메소드를 통해 인텐트를 가져와서 해당 액티비티로 이동 및 현재 액티비티를 종료합니다.

getSupportParentActivityIntent()

sourceActivity(this)에 정의된 상위 액티비티를 대상으로 하는 새로운 인텐트를 리턴합니다. 또한 sourceActivity에 명시적으로 지정된 타겟 액티비티를 실행하기 위해 인텐트를 반환합니다.

supportShouldUpRecreateTask(@NonNull Intent targetIntent)

sourceActivity가 인텐트를 사용하여 뒤로가기(Up) 탐색 시 태스크를 다시 생성해야 하는 경우 true를 반환합니다. 이 메소드를 사용하여 onSupportNavigateUp 메소드에서 새로 TaskStackBuilder를 생성할지가 결정됩니다.

supportNavigateUpTo(@NonNull Intent upIntent)

sourceActivity를 종료하고 sourceActivity에서 upIntent의 액티비티로 이동합니다. upIntent는 메소드에 의해 FLAG_ACTIVITY_CLEAR_TOP 플래그가 세팅되며 적절한 네비게이션에 필요한 다른 메소드는 안드로이드 디자인 가이드에 설명되어 있습니다.

이 방법은 대상과 동일한 Task 내에서 뒤로가기(Up) 탐색을 수행할 때 사용해야 합니다.

onNightModeChanged(@NightMode int mode)

화면의 모드가 바뀔 때 호출됩니다. (다크 or 라이트)

이렇게 AppCompatActivity의 핵심 메소드를 살펴봤습니다. 이 클래스 대부분의 메소드는 super.~를 호출하고 getDelegate()를 통해 동일한 이름의 ~를 호출하는 형태로 구성되어 있었으며, ActionBar, NightMode 중점적으로 구현이 이루어진 것을 확인 할 수 있었습니다. 최신 버전의 안드로이드 기기만 지원할 생각이라면 Activity를 상속받아 사용해도 괜찮겠지만, 호환성을 가져가기 위해서는 AppCompatActivity를 상속받아 사용하면 좋을 것 같습니다.

읽어주셔서 감사합니다. 🙌

--

--