새로운 API 추상화

애플리케이션에서 작업 모음 탭을 최상위 탐색의 기본 형식으로 사용하려고 한다고 가정해 보겠습니다. 안타깝게도 ActionBar API는 Android 3.0(API 수준 11) 이상에서만 사용할 수 있습니다. 따라서 이전 버전의 플랫폼을 실행하는 기기에 애플리케이션을 배포하려면 이전 API를 사용하는 대체 메커니즘을 제공하면서 최신 API를 지원하는 구현을 제공해야 합니다.

이 학습 과정에서는 버전별 구현이 있는 추상 클래스를 사용하여 이전 버전과의 호환성을 제공하는 탭으로 표시된 사용자 인터페이스(UI) 구성요소를 빌드합니다. 이 과정에서는 탭 구성요소를 빌드하는 첫 번째 단계로 새로운 탭 API의 추상화 레이어를 만드는 방법을 설명합니다.

추상화 준비

자바 프로그래밍 언어의 추상화에는 구현 세부정보를 숨기기 위한 하나 이상의 인터페이스나 추상 클래스 만들기가 포함됩니다. 최신 Android API의 경우 추상화를 사용하여 최신 기기에서 현재 API를 사용하고 이전 기기에서 더 잘 호환되는 이전 API로 대체하는 버전 인식 구성요소를 빌드할 수 있습니다.

이 접근법을 사용할 때는 먼저 이전 버전과 호환되는 방식으로 사용할 수 있도록 원하는 최신 클래스를 파악하고 최신 클래스의 공개 인터페이스에 기반해 추상 클래스를 만듭니다. 추상화 인터페이스를 정의할 때는 가능한 한 많이 최신 API를 반영해야 합니다. 이를 통해 이후 버전과의 호환성이 극대화되고 앞으로 더 이상 필요하지 않게 될 때 추상화 레이어를 더 쉽게 삭제할 수 있습니다.

이러한 새로운 API의 추상 클래스를 만들고 나면 런타임 시 여러 구현을 만들고 선택할 수 있습니다. 이전 버전과의 호환성을 위해 이러한 구현은 필요한 API 레벨에 따라 달라질 수 있습니다. 따라서 한 구현에서는 최근에 출시된 API를 사용하고 다른 구현에서는 이전 API를 사용할 수도 있습니다.

추상 탭 인터페이스 만들기

이전 버전과 호환되는 버전의 탭을 만들려면 먼저 애플리케이션에 어떤 기능과 특정 API가 필요한지 파악해야 합니다. 최상위 레벨 섹션 탭의 경우 다음과 같은 기능 요구사항이 있다고 가정합니다.

  1. 탭 표시기는 텍스트와 아이콘을 표시해야 합니다.
  2. 탭은 프래그먼트 인스턴스와 연결될 수 있습니다.
  3. 활동은 탭 변경사항을 수신 대기할 수 있어야 합니다.

이러한 요구사항을 미리 준비하면 추상화 레이어의 범위를 제어할 수 있습니다. 즉, 더 적은 시간으로 추상화 레이어의 여러 구현을 만들고 이전 버전과 호환되는 새로운 구현을 더 빨리 사용하게 됩니다.

탭의 주요 API는 ActionBarActionBar.Tab에 있습니다. 이들은 탭이 버전을 인식할 수 있도록 추상화할 API입니다. 이 프로젝트 예의 요구사항에서는 Honeycomb(API 레벨 11)의 새로운 탭 기능을 활용하면서 Eclair(API 레벨 5)와의 호환성을 요구합니다. 이러한 두 가지 구현과 그 추상 기본 클래스(또는 인터페이스)를 지원하는 클래스 구조 다이어그램은 아래와 같습니다.

추상 기본 클래스 및 버전별 구현의 클래스 다이어그램

그림 1. 추상 기본 클래스 및 버전별 구현의 클래스 다이어그램

추상 ActionBar.Tab

다음과 같이 ActionBar.Tab 인터페이스를 미러링하는 탭을 표시하는 추상 클래스를 만들어 탭 추상화 레이어의 빌드를 시작할 수 있습니다.

Kotlin

sealed class CompatTab(val tag: String) {
    ...
    abstract fun getText(): CharSequence
    abstract fun getIcon(): Drawable
    abstract fun getCallback(): CompatTabListener
    abstract fun getFragment(): Fragment

    abstract fun setText(text: String): CompatTab
    abstract fun setIcon(icon: Drawable): CompatTab
    abstract fun setCallback(callback: CompatTabListener): CompatTab
    abstract fun setFragment(fragment: Fragment): CompatTab
    ...
}

Java

public abstract class CompatTab {
    ...
    public abstract CompatTab setText(int resId);
    public abstract CompatTab setIcon(int resId);
    public abstract CompatTab setTabListener(
            CompatTabListener callback);
    public abstract CompatTab setFragment(Fragment fragment);

    public abstract CharSequence getText();
    public abstract Drawable getIcon();
    public abstract CompatTabListener getCallback();
    public abstract Fragment getFragment();
    ...
}

여기에서 인터페이스 대신 추상 클래스를 사용하여 탭 개체와 활동 연결(코드 스니펫에 표시되지 않음)과 같은 일반 기능의 구현을 간소화할 수 있습니다.

추상 ActionBar 탭 메서드

다음으로, 탭을 만들어 활동에 추가할 수 있는 추상 클래스를 정의합니다(예: ActionBar.newTab()ActionBar.addTab()).

Kotlin

sealed class TabHelper(protected val activity: FragmentActivity) {
    ...

    abstract fun setUp()

    fun newTab(tag: String): CompatTab {
        // This method is implemented in a later lesson.
    }

    abstract fun addTab(tab: CompatTab)

    ...
}

Java

public abstract class TabHelper {
    ...

    public CompatTab newTab(String tag) {
        // This method is implemented in a later lesson.
    }

    public abstract void addTab(CompatTab tab);

    ...
}

다음 과정에서는 이전 및 최신 플랫폼 버전에서 모두 작동하는 TabHelperCompatTab의 구현을 만듭니다.

참고 사항