Android 17은 버전 숫자보다 선언에 가깝다. "운영체제에서 인텔리전스 시스템으로"라는 표현이 공식 릴리스 문서에 등장하는데, 이게 마케팅 수사가 아니라 실제 API 설계에 영향을 미치고 있다. 이번 릴리스에서 주목할 두 가지는 AppFunctions와 강제 적용되는 대화면 리사이징이다. 두 가지 모두 "지금 내 앱에 어떤 영향을 주는가"라는 질문에 대한 답이 있다.
AppFunctions: 앱을 AI 에이전트의 도구로 만들기
Model Context Protocol(MCP)이라는 개념이 서버 사이드에서 먼저 확산되었는데, Android 17은 이것을 온디바이스로 가져온다. AppFunctions는 앱의 핵심 기능을 AI 에이전트가 호출할 수 있는 도구로 노출하는 플랫폼 API다. 앱 안에 무언가를 "할 수 있다"고 선언하면, 기기 위에서 동작하는 AI 에이전트가 그것을 발견하고 실행할 수 있게 된다.
왜 이게 의미 있냐면, 지금까지 AI 연동은 대부분 앱 바깥에서 완결되는 방식이었다. 에이전트가 앱의 내부 상태에 직접 접근하면서 워크플로를 실행하는 구조는 전혀 달랐다. AppFunctions는 이 접근을 표준화하려는 시도다.
Jetpack 라이브러리(현재 alpha)를 사용하면 기존 비즈니스 로직을 크게 변경하지 않고도 함수를 노출할 수 있다.
// build.gradle.kts (app)
dependencies {
implementation("androidx.appfunctions:appfunctions:1.0.0-alpha01")
ksp("androidx.appfunctions:appfunctions-compiler:1.0.0-alpha01")
}
class NoteFunctions(
private val noteRepository: NoteRepository
) {
/**
* 새 메모를 앱에 추가합니다.
*
* @param appFunctionContext 실행 컨텍스트.
* @param title 메모 제목.
* @param content 메모 내용.
*/
@AppFunction(isDescribedByKDoc = true)
suspend fun createNote(
appFunctionContext: AppFunctionContext,
title: String,
content: String
): Note {
return noteRepository.createNote(title, content)
}
}
KDoc 주석이 단순한 문서가 아니라 LLM 툴 호출을 위한 스키마 역할을 한다는 점이 핵심이다. isDescribedByKDoc = true를 설정하면 컴파일러가 KDoc을 파싱해서 함수 설명과 파라미터 메타데이터를 자동으로 생성한다. 주석을 성의 없이 쓰면 에이전트가 함수를 잘못 호출하거나 아예 선택하지 않을 수 있다.
현실적인 한계도 있다. Gemini와의 실제 통합은 현재 비공개 프리뷰 단계라 일반 개발자가 프로덕션에서 쓸 수 있는 시점이 아직 불분명하다. 다만 ADB로 직접 AppFunction을 실행해보는 테스트는 지금도 가능하고, 테스트 에이전트 앱을 통한 시뮬레이션도 제공된다. 연동 준비는 지금 해두는 게 맞다.
대화면 리사이징은 이제 권고가 아니라 요건이다
Android 17부터 대화면 리사이징 지원이 필수 요건으로 바뀐다. 580만 대 이상의 대화면 기기가 이미 사용자 손에 있고, Android 스택 기반으로 재구성된 ChromeOS 차기 버전이 출시를 앞두고 있다는 맥락에서 나온 결정이다. "적응형 우선(adaptive-first)" 개발 표준으로의 전환을 공식화한 것이다.
실질적으로 달라지는 건 resizeableActivity 설정이다. 지금까지는 android:resizeableActivity="false"로 다중 창이나 자유형 창 지원을 거부할 수 있었다. Android 17 타깃 앱에서는 이 옵션이 무력화된다.
<!-- Android 17 타깃 앱에서 이 설정은 무시됨 -->
<activity
android:name=".MainActivity"
android:resizeableActivity="false" />
문제가 생기는 지점은 명확하다. 세로 고정 레이아웃, 하드코딩된 화면 비율, onConfigurationChanged를 재정의하면서 실제로 레이아웃을 다시 그리지 않는 패턴들이 모두 깨진다. 액티비티가 재생성되는 대신 창 크기가 동적으로 변하는 상황을 제대로 처리하는지 먼저 확인해야 한다.
WindowSizeClass를 아직 도입하지 않은 프로젝트라면 지금이 진입 시점이다.
// build.gradle.kts
dependencies {
implementation("androidx.window:window:1.4.0")
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val windowMetrics = WindowMetricsCalculator
.getOrCreate()
.computeCurrentWindowMetrics(this)
val widthDp = windowMetrics.bounds.width() /
resources.displayMetrics.density
val sizeClass = when {
widthDp >= 840f -> WindowWidthSizeClass.EXPANDED
widthDp >= 600f -> WindowWidthSizeClass.MEDIUM
else -> WindowWidthSizeClass.COMPACT
}
// sizeClass에 따라 레이아웃 분기
}
}
WindowSizeClass는 픽셀 단위 분기보다 훨씬 안정적인 기준점을 제공한다. 기기마다 화면 밀도가 달라서 픽셀 기준으로 분기하면 예외 케이스가 계속 생긴다.
지금 당장 확인할 것
AppFunctions는 준비를 시작하되 프로덕션 의존은 아직 이르다. 알파 라이브러리를 붙여보고 KDoc 품질을 다듬어두는 것 자체는 부담이 크지 않다. 반면 대화면 리사이징 대응은 targetSdkVersion을 올리기 전에 반드시 완료해야 한다. 특히 액티비티에서 configChanges를 직접 처리하거나 화면 비율을 고정한 코드가 있다면 먼저 찾아내는 게 순서다.
Android 17이 "인텔리전스 시스템"이라는 선언을 얼마나 실현하느냐는 AppFunctions 생태계가 어떻게 열리느냐에 달려 있다. 지금 당장의 실질적 변화는 적응형 레이아웃 강제화다.
※ 본 글은 정보 제공 목적이며 특정 제품·서비스의 추천이 아닙니다.
'안드로이드' 카테고리의 다른 글
| Kotlin 빌드 도구의 새 이름: Kotlin Toolchain 0.11이 바꾸는 것들 (0) | 2026.06.29 |
|---|---|
| 프롬프트 한 줄로 앱이 생긴다면, 개발자의 일은 어디서 시작하는가 (0) | 2026.06.29 |
| 크래시 리포트만 보고 있다면, 장애의 절반을 놓치고 있는 것이다 (0) | 2026.06.29 |
| list.map{}이 느린 건 CPU 때문이 아니다 (0) | 2026.06.26 |
| Kotlin 2.4가 바꾸는 것: 15년 된 언어가 지금 가장 흥미로운 이유 (0) | 2026.06.25 |