AppCompatActivity
우리는 일반적으로 액티비티를 선언할 때, Activity
를 상속받아서 작성하곤 합니다. 그런데 사실, Activity
는 종류가 여러가지 존재합니다. 아래 그림과 같은 상속 구조를 가지며, 최종적으로 AppCompatActivity
까지 자식을 가지고 있습니다. 본 글에서는 가장 하위 클래스인 AppCompatActivity
에 대해 알아보고자 합니다. 일단 Compat이라는 이름부터 호환성을 의미하는 compatibility의 줄임말임을 유추해볼 수 있는데요. 어떤 호환성을 의미하는 것이고 어떻게 지원해준다는 걸까요?
Android 3.0(API Level 11)부터는 기본적으로 Activity
들은 Appbar
로 모두 ActionBar
를 가지고 있습니다. 이런 특정 버전부터 지원되는 ActionBar
를 해당 버전 이하의 버전에도 적용할 수 있도록 지원해주는 Activity
가 바로 AppCompatActivity
입니다.
AppCompatActivity
는 크게 다음과 같은 3가지 특징을 가지고 있습니다.
setSupportActionBar(Toolbar)
API를 사용하여 action item, navigation mode 등을 포함하는 action bar를 지원합니다.Theme.AppCompat.DayNight
테마를 사용하며AppCompatDelegate.setDefaultNightMode(int)
API를 사용하여 다크 모드를 지원합니다.getDrawerToggleDelegate()
API를 사용하여DrawerLayout
과 통합합니다.
⚠️ 이 클래스를 확장하는 모든 액티비티는 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()
를 통해 접근하는 AppCompatDelegateImpl
의 setSupportActionBar
의 구현은 다음과 같습니다.
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
를 상속받아 사용하면 좋을 것 같습니다.