Skip to main content

android-api-diff

Inspect Android framework Java and AIDL APIs across versions with the android-api-diff CLI. Use when finding an Android API across AOSP repositories, fetching the complete content of a tagged source file, comparing signatures or availability by Android version, explaining missing APIs, generating Java hidden-API access code, or explicitly prewarming the local query cache.

소스 정보

저장소
gkd-kit/gkd
최근 소스 활동
2026년 11월 6일 05:59
감지된 SKILL.md 언어
영어
스타
44,337
포크
2,120

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
2 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
android-api-diff
description
Inspect Android framework Java and AIDL APIs across versions with the android-api-diff CLI. Use when finding an Android API across AOSP repositories, fetching the complete content of a tagged source file, comparing signatures or availability by Android version, explaining missing APIs, generating Java hidden-API access code, or explicitly prewarming the local query cache.
# Android API Diff Use the `android-api-diff` CLI as the only tool interface. Keep its default JSON output so results remain machine-readable. ## Route the request - Run `generate` when the user wants Java hidden-API access code. It performs the version query internally, so never call `query` first. - Run `query` when the user wants signatures, version ranges, availability, missing reasons, or source metadata. - Run `search` for fuzzy repository/path discovery or Java reference matching. - Run `source` for the complete content of an exact repository, path and tag. If only an API name is known, use `search` and select its candidate `repo` and `path`. - Run `preload` only when the user explicitly asks to preload several APIs. Always quote API names because constructors and member references can contain shell-sensitive characters. ```sh android-api-diff search "ContentObserver()" android-api-diff search "platform/frameworks/base/core/java/android/content/pm/UserInfo.java" android-api-diff source --repo platform/frameworks/base --path core/java/android/accessibilityservice/AccessibilityButtonController.java --tag android-17.0.0_r1 android-api-diff query --name "IActivityManager.getTasks" --min-sdk 28 android-api-diff generate --name "ActivityThread.currentApplication" --min-sdk 28 android-api-diff preload "ContentObserver()" "IActivityManager.getTasks" --min-sdk 28 ``` Omit `--min-sdk` unless the user provides a minimum Android API level. The CLI then uses its built-in default. ## Interpret results Treat exit code `0` together with top-level `ok: true` as success. Read the operation result from the top-level `result` field. `search` returns `result.candidates` with repository-relative `repo` and `path`, indexed `availableTags`, and reference metadata. `query` and `generate` accept `--name <reference>` or `--repo <repo> --path <path> --target <reference>`. Use `--anchor-tag <tag>` to select a specific initial definition. Without a target, `query` pins the exact file; type/member queries follow repository/path moves by fully qualified type identity. ## Select a source Search text and `--name` accept an API reference, a file path, or a full repository prefix followed by the search text. For example: ```sh android-api-diff query --name "platform/frameworks/base/core/java/android/content/pm/UserInfo.java" android-api-diff query --name "platform/frameworks/base/UserInfo.name" ``` A recognized repository prefix limits matching to that repository before matching the remaining text. Use the complete name, such as `platform/frameworks/base`, not the shorthand `base`. Repository-prefixed searches stay within that repository; use an unprefixed API reference to follow cross-repository moves. An explicit `--repo ... --path ... --target ...` selects the initial definition and still follows type identity across moves; it is not equivalent to a repository-prefixed search. When a file path appears in multiple repositories, including in different historical tags, use `repo/path` to identify the intended repository. A unique path can remain repository-relative. File-path queries inspect files, not a member formerly entered in the search text; use an API reference or `--target` for member queries. Default selection ranks suffix first (`.java` before `.aidl`, including `I`-prefixed interfaces), then repository (`platform/frameworks/base` before other repositories), then configured path preferences, with repository/path lexical order breaking ties. Simple searches choose the first matching definition rather than requiring manual selection for duplicate names. Inspect the selected source in the result and use explicit source options when the user intends another definition. Explicit selection and known historical redirect/superseded-definition rules remain applicable. ## Interpret version coverage Read `result.tags` for each tag's actual source and status. `unknown` and `ambiguous` are not evidence of API absence. The bundled index contains audited snapshots, not every enumerated release tag. Code generation rejects incomplete or ambiguous histories. Candidate metadata alone does not establish availability. For `query`, describe range endpoints as the first or last tag checked in the current snapshot. A `last-checked` endpoint is not a promise that no later revision exists. For member queries, treat `result.overloads` as the source of truth. Each item has a stable `overloadId`, its latest checked `signature` and `member`, and independent `ranges`. A range with `missingReason: "overload-not-found"` means the member name exists in that source revision but that specific parameter signature does not. Use top-level `result.ranges[].overloadIds` only when describing which overloads were available together. On a nonzero exit code, read the structured JSON error from stderr and report its `error.code` and `error.message`. Do not add an automatic retry: the CLI network layer already retries transient fetches. ## Choose an interface constant access strategy Four strategies are supported and have already been validated in the companion remap repository. Choose based on the user's build and value requirements; do not require another feasibility experiment unless the user requests one. | Strategy | When to use it | Declaration or access | | ----------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | Reflection | Read the device's value without a remapped field access | Read the original interface field reflectively. | | Interface stub | Preserve runtime field access in a compatible remap build | Initialize the interface field with `RemapStub.value()`. | | Consistent constant | Embed a supported primitive expression that agrees across checked versions | Keep the original initializer in the generated interface. | | Implementing-class stub | Read the device's value through a known platform class implementing the interface, without `RemapStub.value()` | Declare a `public static`, non-final field with no initializer in that class's remap stub. | The current `generate` command automatically chooses the consistent-constant strategy for supported primitive initializers whose token sequences match across checked definitions, ignoring whitespace and comments. It does not evaluate expressions: `0x1` and `(1 << 0)` differ. Constant references, unsupported expressions, missing initializers, differing definitions, and non-primitive types fall back to `RemapStub.value()`. Agreement covers only checked versions; do not download all versions to strengthen this conclusion. Reflection and implementing-class stubs are adaptations of the generated code, not CLI flags or automatic generator fallbacks. Honor an explicitly selected strategy. For an interface/R8 incompatibility, use a consistent constant when the generated result supports it; otherwise prefer a known suitable platform implementing class, or reflection when no suitable class is known. Do not present the `RemapStub.value()` fallback as resolving that incompatibility. For example, access `IBinder.SHELL_COMMAND_TRANSACTION` through a stub mapped to the platform's `Binder` implementation: ```java @li.songe.remap.RemapType(android.os.Binder.class) public class BinderHidden { public static int SHELL_COMMAND_TRANSACTION; } ``` Read `BinderHidden.SHELL_COMMAND_TRANSACTION` at the call site. Keep the field name and type matching the original interface declaration; omit both `final` and an initializer. This strategy also applies to reference types and values that differ between versions. Map to the real platform implementing class; merely declaring a field in an unmapped application subclass creates a separate field. Use these declarations for reads, since the original interface field is final. ## Handle a missing CLI If `android-api-diff` is not installed, stop and tell the user to run: ```sh npm install --global android-api-diff@latest android-api-diff skill install ``` Run the Skill command from the root of the current Git or Gradle project so it remains project-scoped. Do not implement or simulate version checks. The package manager owns CLI update detection and upgrades.
GitHub에서 보기