새로운 API 추상화
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
애플리케이션에서 작업 모음 탭을 최상위 탐색의 기본 형식으로 사용하려고 한다고 가정해 보겠습니다. 안타깝게도 ActionBar
API는 Android 3.0(API 수준 11) 이상에서만 사용할 수 있습니다. 따라서 이전 버전의 플랫폼을 실행하는 기기에 애플리케이션을 배포하려면 이전 API를 사용하는 대체 메커니즘을 제공하면서 최신 API를 지원하는 구현을 제공해야 합니다.
이 학습 과정에서는 버전별 구현이 있는 추상 클래스를 사용하여 이전 버전과의 호환성을 제공하는 탭으로 표시된 사용자 인터페이스(UI) 구성요소를 빌드합니다. 이 과정에서는 탭 구성요소를 빌드하는 첫 번째 단계로 새로운 탭 API의 추상화 레이어를 만드는 방법을 설명합니다.
추상화 준비
자바 프로그래밍 언어의 추상화에는 구현 세부정보를 숨기기 위한 하나 이상의 인터페이스나 추상 클래스 만들기가 포함됩니다. 최신 Android API의 경우 추상화를 사용하여 최신 기기에서 현재 API를 사용하고 이전 기기에서 더 잘 호환되는 이전 API로 대체하는 버전 인식 구성요소를 빌드할 수 있습니다.
이 접근법을 사용할 때는 먼저 이전 버전과 호환되는 방식으로 사용할 수 있도록 원하는 최신 클래스를 파악하고 최신 클래스의 공개 인터페이스에 기반해 추상 클래스를 만듭니다. 추상화 인터페이스를 정의할 때는 가능한 한 많이 최신 API를 반영해야 합니다. 이를 통해 이후 버전과의 호환성이 극대화되고 앞으로 더 이상 필요하지 않게 될 때 추상화 레이어를 더 쉽게 삭제할 수 있습니다.
이러한 새로운 API의 추상 클래스를 만들고 나면 런타임 시 여러 구현을 만들고 선택할 수 있습니다. 이전 버전과의 호환성을 위해 이러한 구현은 필요한 API 레벨에 따라 달라질 수 있습니다. 따라서 한 구현에서는 최근에 출시된 API를 사용하고 다른 구현에서는 이전 API를 사용할 수도 있습니다.
추상 탭 인터페이스 만들기
이전 버전과 호환되는 버전의 탭을 만들려면 먼저 애플리케이션에 어떤 기능과 특정 API가 필요한지 파악해야 합니다. 최상위 레벨 섹션 탭의 경우 다음과 같은 기능 요구사항이 있다고 가정합니다.
- 탭 표시기는 텍스트와 아이콘을 표시해야 합니다.
- 탭은 프래그먼트 인스턴스와 연결될 수 있습니다.
- 활동은 탭 변경사항을 수신 대기할 수 있어야 합니다.
이러한 요구사항을 미리 준비하면 추상화 레이어의 범위를 제어할 수 있습니다. 즉, 더 적은 시간으로 추상화 레이어의 여러 구현을 만들고 이전 버전과 호환되는 새로운 구현을 더 빨리 사용하게 됩니다.
탭의 주요 API는 ActionBar
및 ActionBar.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
...
}
자바
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)
...
}
자바
public abstract class TabHelper {
...
public CompatTab newTab(String tag) {
// This method is implemented in a later lesson.
}
public abstract void addTab(CompatTab tab);
...
}
다음 과정에서는 이전 및 최신 플랫폼 버전에서 모두 작동하는 TabHelper
및 CompatTab
의 구현을 만듭니다.
참고 사항
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Abstract the new APIs\n\nSuppose you want to use [action bar tabs](/guide/topics/ui/actionbar#Tabs) as the primary form of top-level navigation in your application. Unfortunately, the [ActionBar](/reference/android/app/ActionBar) APIs are only available in Android 3.0 or later (API level 11+). Thus, if you want to distribute your application to devices running earlier versions of the platform, you need to provide an implementation that supports the newer API while providing a fallback mechanism that uses older APIs.\n\nIn this class, you build a tabbed user interface (UI) component that uses abstract classes with version-specific implementations to provide backward-compatibility. This lesson describes how to create an abstraction layer for the new tab APIs as the first step toward building the tab component.\n\nPrepare for abstraction\n-----------------------\n\n[Abstraction](https://en.wikipedia.org/wiki/Abstraction_(computer_science)) in the Java programming language involves the creation of one or more interfaces or abstract classes to hide implementation details. In the case of newer Android APIs, you can use abstraction to build version-aware components that use the current APIs on newer devices, and fallback to older, more compatible APIs on older devices.\n\nWhen using this approach, you first determine what newer classes you want to be able to use in a backward compatible way, then create abstract classes, based on the public interfaces of the newer classes. In defining the abstraction interfaces, you should mirror the newer API as much as possible. This maximizes forward-compatibility and makes it easier to drop the abstraction layer in the future when it is no longer necessary.\n\nAfter creating abstract classes for these new APIs, any number of implementations can be created and chosen at runtime. For the purposes of backward-compatibility, these implementations can vary by required API level. Thus, one implementation may use recently released APIs, while others can use older APIs.\n\nCreate an abstract tab interface\n--------------------------------\n\nIn order to create a backward-compatible version of tabs, you should first determine which features and specific APIs your application requires. In the case of top-level section tabs, suppose you have the following functional requirements:\n\n1. Tab indicators should show text and an icon.\n2. Tabs can be associated with a fragment instance.\n3. The activity should be able to listen for tab changes.\n\nPreparing these requirements in advance allows you to control the scope of your abstraction layer. This means that you can spend less time creating multiple implementations of your abstraction layer and begin using your new backward-compatible implementation sooner.\n\nThe key APIs for tabs are in [ActionBar](/reference/android/app/ActionBar) and [ActionBar.Tab](/reference/android/app/ActionBar.Tab). These are the APIs to abstract in order to make your tabs version-aware. The requirements for this example project call for compatibility back to Eclair (API level 5) while taking advantage of the new tab features in Honeycomb (API Level 11). A diagram of the class structure to support these two implementations and their abstract base classes (or interfaces) is shown below.\n\n**Figure 1.** Class diagram of abstract base classes and version-specific implementations.\n\nAbstract ActionBar.Tab\n----------------------\n\nGet started on building your tab abstraction layer by creating an abstract class representing a tab, that mirrors the [ActionBar.Tab](/reference/android/app/ActionBar.Tab) interface: \n\n### Kotlin\n\n```kotlin\nsealed class CompatTab(val tag: String) {\n ...\n abstract fun getText(): CharSequence\n abstract fun getIcon(): Drawable\n abstract fun getCallback(): CompatTabListener\n abstract fun getFragment(): Fragment\n\n abstract fun setText(text: String): CompatTab\n abstract fun setIcon(icon: Drawable): CompatTab\n abstract fun setCallback(callback: CompatTabListener): CompatTab\n abstract fun setFragment(fragment: Fragment): CompatTab\n ...\n}\n```\n\n### Java\n\n```java\npublic abstract class CompatTab {\n ...\n public abstract CompatTab setText(int resId);\n public abstract CompatTab setIcon(int resId);\n public abstract CompatTab setTabListener(\n CompatTabListener callback);\n public abstract CompatTab setFragment(Fragment fragment);\n\n public abstract CharSequence getText();\n public abstract Drawable getIcon();\n public abstract CompatTabListener getCallback();\n public abstract Fragment getFragment();\n ...\n}\n```\n\nYou can use an abstract class instead of an interface here to simplify the implementation of common features such as association of tab objects with activities (not shown in the code snippet).\n\nAbstract ActionBar tab methods\n------------------------------\n\nNext, define an abstract class that allows you to create and add tabs to an activity, like [ActionBar.newTab()](/reference/android/app/ActionBar#newTab()) and [ActionBar.addTab()](/reference/android/app/ActionBar#addTab(android.app.ActionBar.Tab)): \n\n### Kotlin\n\n```kotlin\nsealed class TabHelper(protected val activity: FragmentActivity) {\n ...\n\n abstract fun setUp()\n\n fun newTab(tag: String): CompatTab {\n // This method is implemented in a later lesson.\n }\n\n abstract fun addTab(tab: CompatTab)\n\n ...\n}\n```\n\n### Java\n\n```java\npublic abstract class TabHelper {\n ...\n\n public CompatTab newTab(String tag) {\n // This method is implemented in a later lesson.\n }\n\n public abstract void addTab(CompatTab tab);\n\n ...\n}\n```\n\nIn the next lessons, you create implementations for `TabHelper` and `CompatTab` that work across both older and newer platform versions.\n\n### You should also read\n\n- [Action Bar](/guide/topics/ui/actionbar)\n- [Action Bar Tabs](/guide/topics/ui/actionbar#Tabs)"]]