arXiv:2604.14943v1 [cs.SE] 16 Apr 2026
Towards Understanding Android APIs: Official Lists, Vendor Customizations, and Real-World Usage Sinan Wang∗
Qi Zhang
Jiacheng Li
Southern University of Science and Technology Shenzhen, Guangdong, China [email protected]
Hong Kong University of Science and Technology Hong Kong SAR, China [email protected]
University of Maryland College Park, MD, USA [email protected]
Lili Wei
Yida Tao
Yepang Liu∗†
McGill University Montréal, QC, Canada [email protected]
Southern University of Science and Technology Shenzhen, Guangdong, China [email protected]
Southern University of Science and Technology Shenzhen, Guangdong, China [email protected]
Abstract
CCS Concepts
Android apps are built on APIs that abstract core Android system functionalities. These APIs are officially documented in multiple files distributed with the Android source code or SDK, which we collectively refer to as Android API Lists (AALs). Prior Android research has relied on specific AALs, often treating them as interchangeable ground truth. However, recent studies suggest that different AALs can lead to substantially different research outcomes, raising concerns about the validity and reproducibility of Android API-based analyses. To address this issue, we present the first indepth empirical study of four official AALs that are widely used in prior work. We systematically characterize their contents and analyze their evolution across Android releases. We then perform a fine-grained comparison of the APIs recorded in each AAL to uncover their underlying API inclusion policies and inconsistencies. To assess the practical impact of these differences, we further examine API availability on nine Android devices, including both stock Android and vendor-customized systems. Finally, we analyze API usage in 17,759 real-world Android apps (including open-source apps, commercial apps, and malware) to quantify how the choice of AAL affects empirical Android research. Our results reveal that official AALs are neither stable nor mutually consistent, and that discrepancies among them can substantially influence research conclusions. We also observe that vendor-customized APIs are actively used by normal apps, yet remain largely overlooked by existing studies. Based on these findings, we discuss their implications for Android API-based research and provide actionable suggestions to help researchers select and interpret AALs more reliably.
• Software and its engineering → Development frameworks and environments; Software libraries and repositories.
∗ Sinan Wang and Yepang Liu are affiliated with the Research Institute of Trustworthy Autonomous Systems (RITAS) at Southern University of Science and Technology. † Yepang Liu is the corresponding author.
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than the author(s) must be honored. Abstracting with credit is permitted. To copy otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from [email protected]. EASE 2026, 9–12 June, 2026, Glasgow, Scotland, United Kingdom © 2018 Copyright held by the owner/author(s). Publication rights licensed to ACM. ACM ISBN 978-1-4503-XXXX-X/18/06 https://doi.org/XXXXXXX.XXXXXXX
Keywords Android, Android API List, Non-SDK Interfaces. ACM Reference Format: Sinan Wang, Qi Zhang, Jiacheng Li, Lili Wei, Yida Tao, and Yepang Liu. 2018. Towards Understanding Android APIs: Official Lists, Vendor Customizations, and Real-World Usage. In Proceedings of The 30th International Conference on Evaluation and Assessment in Software Engineering (EASE 2026). ACM, New York, NY, USA, 12 pages. https://doi.org/XXXXXXX.XXXXXXX
1
Introduction
The Android framework provides a set of APIs that abstract the core Android system functionalities and hardware features, thereby supporting the functioning of running apps. These Android APIs ease app development, but they also bring API compatibility issues [50]. It has been shown that those change-prone Android APIs can trigger more developers’ discussions [35] and even threat to the apps’ ratings [34]. At the user end, one may find a particular app only works on specific Android versions or devices, causing poor user experience. Android SDK [11] provides facilities to reduce developers’ maintaining effort in this situation. For example, AndroidX [29] helps maintain an API’s backward compatibility. Lint [5] is an another SDK tool, which provides a rule-based code smell scanning service. It can detect certain API compatibility issues [24, 48] in the application source code. However, Lint’s performance have been shown to be weak [23, 48, 50, 52]. These compatibility issues attract researchers’ attention. Wei et al. [50] developed FicFinder, a tool for identifying compatibility issues via pairs of APIs and their respective issue-triggering contexts (i.e., API-context pairs). However, FicFinder depends on a set of manually written API-context pairs, limiting its practical usability in the evolving Android ecosystem. Later on, static compatibility issue detectors mostly involve a separate module for systematic API harvesting. For example, CiD [31] has an API Lifecycle Modeling module. It reads the source code of the Android framework and extracts APIs’ lifetimes for API-based issue
EASE 2026, 9–12 June, 2026, Glasgow, Scotland, United Kingdom
detection. IctApiFinder [22], another compatibility issue detector, collects all APIs in the android.jar files bundled in Android SDK. Mahmud et al. proposed ACID [39], which leverages Android API differences report [9] for detecting two kinds of API compatibility issues. As pointed out by Liu et al. [37], tools that have systematic API harvesting methods can detect significantly more issues than those that do not. They also found that tools using different sources of API knowledge output few overlapped results. The research work mentioned so far all rely on specific Android API knowledge. The accuracy of the research outcomes significantly depend on the utilization of carefully curated API lists. We call such curated API files Android API Lists (AALs for short). Despite the pervasive uses of AALs in previous work, little is known about whether they faithfully represent the Android API knowledge. In fact, we revealed that, even in the same Android version, different AALs may record distinct API knowledge, and the recorded APIs in an AAL may not reflect the actual APIs in a running Android device. For example, on Android 13, four Java methods were removed from the AAL current.txt, though they retained in the Android framework and could be used by normal apps. This AAL is utilized by the state-of-the-art API compatibility issue detector, PSDroid. Incomplete API inclusion brings false negatives to PSDroid’s detection results. In other words, incomplete or incorrect AALs pose substantial threats to various research outcomes. Our contribution: A better understanding of the Android API lists helps Android researchers and practitioners make more informed decisions in the future. To this end, we conducted the first in-depth study about four official AALs under six Android release versions. Specifically, we studied how these AALs include APIs from Android system, how they change along with the evolution of Android platform, and how they are different from each other. We further explore the API existence on nine real Android devices and the API usage situations in 17,759 real Android apps. Our study demystifies the API instability and inconsistencies among the four official AALs, as well as their impact on the Android ecosystem. Our research reveals the following key findings: (1) AALs exhibit substantial inconsistencies, with only a few (~10%) APIs shared among all investigated AALs. (2) AALs may include considerable amount of synthesized APIs, which are presented in some AALs but absent from the Android source code or real Android devices. (3) No single AAL completely records all APIs, especially for non-SDK interfaces and vendor-customized APIs. (4) AALs’ API inclusion policies are unstable, which will change during platform evolution. We also highlight research opportunities in the context of Android APIs, with an emphasis on the non-SDK APIs and vendorcustomized APIs. To support future work, we release all our research artifacts on https://github.com/sqlab-sustech/AAL-artifacts, including AAL dataset, source code of tools, and experiment results.
2 Android API Lists 2.1 Research Scope Table 1 lists recent research work that rely on specific Android API knowledge. Among the listed papers, five of them directly utilize the bundled Android API lists from either Android source
Wang et al.
code or Android SDK, which consist of the four bundled AALs involved in our study. To ease presentation, we denote each of them according to their file extensions, that is, JAR for android.jar, XML for api-versions.xml, TXT for current.txt and CSV for hiddenapi-flags.csv, respectively. We do not investigate APIs from the web documentation due to potential inaccuracies, as highlighted in [28]. We also do not consider Android source code as a separate AALs. Instead, we place confidence in it as a dependable reference when investigating the correctness of the investigated AALs.
2.2
API Definitions
Android framework APIs are written in Java, which means they are either fields or methods of some Java classes. Hence we consider APIs to be these three types of Java language constructs. To uniquely identify a Java API, we follow the practice of Java reflection [33] on how it retrieves classes and their members. Specifically, we denote a class by its full_class_name (a.k.a. fully-qualified name), which consists of the class’s package and its short name. A field in the class is denoted by a pair of character strings: ⟨full_class_name, field_name⟩ A method can be uniquely identified by a 3-tuple of strings: ⟨full_class_name, method_name, parameter_list⟩ while the last term is a (possibly empty) list of strings of the method’s formal parameter types. With such notation, constructors can be denoted as methods that have a special name "<init>" [2]. It is worth noting that our notation sufficiently includes nested classes and their members. Also notice that callbacks are special methods whose control are inverted to the application framework [23], thus our notation can cover them without additional adaptation.
2.3
The JAR List
package android.app; import android.content.ContextWrapper; public class Service extends ContextWrapper { public static final int START_STICKY = 1; // other API fields...
}
@Deprecated public final void stopForeground(boolean removeNotification) { throw new RuntimeException("Stub!"); } public final void stopSelf() { throw new RuntimeException("Stub!"); } // other API methods...
Figure 1: Decompiled code snippet in the android.jar file The android.jar file is an essential part of the Android SDK. It can be downloaded by the SDK Manager tool [11], or built through the sdk target from the Android source code. The file contains a collection of compiled Java classes and resources that define the
Towards Understanding Android APIs: Official Lists, Vendor Customizations, and Real-World Usage
EASE 2026, 9–12 June, 2026, Glasgow, Scotland, United Kingdom
Table 1: Tools or studies related to Android APIs, and how they obtain API knowledge Tool/Study
Year
Research Topic
Depending API Knowledge
AAL
PSDroid [54] ACID [40] APIMatchmaker [57] Yang et al. [55] A3 [28] RAPID [53] AppEvolve [21] IctApiFinder [22] CiD [31] CDA [32] Li et al. [30] McDonnell et al. [42]
2023 2023 2022 2022 2020 2020 2019 2018 2018 2018 2016 2013
API compatibility issue detection API compatibility issue detection API recommendation empirical study of non-SDK interfaces API migration API compatibility issue detection API migration API compatibility issue detection API compatibility issue detection empirical study of deprecated APIs empirical study of inaccessible APIs empirical study of API evolution
current.txt file in Android source code API differences report parse Android source code for APIs with lifetime hiddenapi-flags.csv file from Android source code API documentation, Android source code api-versions.xml file from Android SDK API differences report android.jar file from Android SDK parse Android source code for APIs with lifetime parse Android source code for all deprecated APIs parse Android source code for all hidden/internal APIs api-versions.xml file from Android SDK
TXT CSV XML JAR XML
Android application framework at a specific API-level. By linking this file, developers gain access to the Android framework classes, fields, and methods. This allows them to write Java code that utilizes the platform’s features, such as telephony or locationing services. Notably, this file does not contain the actual implementation of API methods. Their actual implementations reside in the running devices. Figure 1 shows the class Service in android.jar at APIlevel 33, which contains one integer constant field, and two method stubs. 2.3.1 API Extraction. We used Soot [27] to load all classes in an android.jar file. Then, for each successfully loaded class, we iterated over its field and method lists to obtain all the declared APIs. We also extracted classes that have no declared members, such as the Serializable interface. It is worth mentioning that, we do not distinguish abstract classes, interfaces, enum classes, or annotation declarations. All of them can be regarded as some special forms of Java classes, while their conceptual differences do not affect the results of our study.
2.4
supports quick lookup for the status of an API (e.g., available, deprecated) at certain API-levels. Figure 2 shows a snippet of this file, which displays the same API information as Figure 1. However, it provides more information about the API’s lifetime, such as when the API was deprecated. Notably, this file also contains removed APIs, indicated by the removed attribute on their XML elements. This enables Lint to determine an API’s lifetime. 2.4.1 API Extraction. We directly parsed the api-versions.xml file to extract all the declared APIs. In particular, we dropped out those elements having a removed attribute, as we are interested in the available APIs at a specific API-level.
2.5
package android.content { public abstract class Context { // constructor ctor public Context(); // API methods... method public final String getString(int,java.lang.Object...); method public final <T> T getSystemService(Class<T>); method public abstract String getSystemServiceName(Class<?>);
The XML List
<class name="android/app/Service" since="1"> <extends name="android/content/ContextWrapper"/> <method name="setForeground(Z)V" removed="11"/> <method name="stopForeground(Z)V" since="5" deprecated="33"/> <method name="stopSelf()V"/> <!−− other API methods... −−> <field name="START_STICKY" since="5"/> <!−− other API fields... −−> </class>
Figure 2: A class in the api-versions.xml file The api-versions.xml file is also bundled in the Android SDK. It is generated along with the android.jar file when building SDK. By referencing this file, one can determine the minimum and maximum API-levels of an API. This information is important for ensuring their apps are compatible with the desired range of Android versions. Lint leverages this file to build a database, which
The TXT List
}
}
// API fields... field public static final int MODE_WORLD_READABLE = 1; // 0x1 field public static final String WINDOW_SERVICE = "window";
Figure 3: A simplified class entry in the current.txt file The TXT list refers to the current.txt files in Android [13]. It is automatically updated once APIs are changed and the update-api build target is triggered [3]. PSDroid [54] utilizes this file to build an API lifetime database, which records when an API was being added to and deprecated from the Android framework. A major difference between the TXT list and the other AALs is that this file records the source-level API signatures. This format retains front-end language features that will be erased in bytecode, for examples, generic types or variable arguments (a.k.a. vararg). Source-level signatures help developers better understand
EASE 2026, 9–12 June, 2026, Glasgow, Scotland, United Kingdom
package Id { 𝝓 −→𝑡 𝝓 [𝑡 { Id] (rule 1, package definition) class Id[.Id] ∗ [(extends | implements) Type] { 𝜽 −→𝑡 𝜽 [𝑡 { Id [.Id] ∗ ] C −→𝑡 C ∪ {⟨𝝓 [𝑡].𝜽 [𝑡]⟩} (rule 2, class definition) field Type Id [= Value]; F −→𝑡 F ∪ {⟨𝝓 [𝑡].𝜽 [𝑡], Id⟩} (rule 3, field definition)
Wang et al.
𝝓 [𝑡], the current class name 𝜽 [𝑡], and a mapping of generic type bound 𝛀 ⊂ {⟨GenericType ↦→ Type⟩ ∗ }. The parser is shown in Figure 4. In rule 1, the action 𝝓 [𝑡 { Id] saves the current package name Id. In rule 2, C ∪ {⟨𝝓 [𝑡].𝜽 [𝑡]⟩} means concatenating current package name and class name with a dot "." and adds it into the set of classes. Similarly, rule 3 and 4 extract the member fields and methods in the current class. Rules 5 and 6 specify the semantic actions for generic types: creating the mapping ⟨Param ↦→ Type⟩ into 𝛀 for bounded generic types (rule 5.1), or converting the class to Object for unbounded generic types (rule 5.2). When encountering type parameters, the parser converts them to their bound type names (rule 6).
2.6 method [GenericTypeList] Type Id ([TypeList]); M −→𝑡 M ∪ {⟨𝝓 [𝑡].𝜽 [𝑡], Id, TypeList⟩} 𝛀 −→𝑡 ∅ (rule 4, method declaration) Param extends Type 𝛀 −→𝑡 𝛀 ∪ {⟨Param ↦→ Type⟩} (rule 5.1, bounded generic type) Param 𝛀 −→𝑡 𝛀 ∪ {⟨Param ↦→ "java.lang.Object"⟩} (rule 5.2, unbounded generic type) Id[.Id’] ∗ [.Id’] ∗ = 𝜖 (if ∃.Ω[𝑖𝑑] then Ω[Id] else Id) { Id (rule 6, generic type name) Figure 4: Parsing the TXT list file the underlying semantics of an API. However, the signatures can be different from that being referenced in the Android bytecode. Figure 3 shows an example class entry in the current.txt file at API-level 33. The file is written in a special context-free grammar, in which each class has multiple sections: its constructors, methods, fields, and so on. In Figure 3, the method getString has a vararg parameter Object..., which will be converted into Object[] in compilation. The next two methods have a type argument T and an unbounded wildcard generic type parameter, respectively. After compilation, the generic types are replaced by Object, and the type parameters are erased. Then their method declarations become: String getString(int, Object[]) Object getSystemService(Class) String getSystemServiceName(Class)
PSDroid employs such conversion to its extracted APIs, thus their database can be utilized to analyze API usages in Android bytecode. 2.5.1 API Extraction. The TXT list is written in a special grammar that involves many source-level language features. Following the API definitions in Section 2.2, we implemented a parser to collect three sets of APIs: classes C, fields F, and methods M. The parser also manipulates three state variables: the current package name
The CSV List
Landroid/content/Context;−>MODE_WORLD_READABLE:I,public−api,sdk Landroid/content/Context;−>canStartActivityForResult()Z,max− ↩→ target−r Landroid/content/Context;−>destroy()V,blocked Landroid/content/Context;−>getString(I[Ljava/lang/Object;)Ljava/ ↩→ lang/String;,public−api,sdk Landroid/content/Context;−>getSystemService(Ljava/lang/Class;) ↩→ Ljava/lang/Object;,public−api,sdk
Figure 5: Sample lines from the hiddenapi-flags.csv file Starting from Android 9, a series of APIs, called non-SDK interfaces, were restricted in usage from normal Android apps [6]. They are internally used by the Android system and are subject to change without notification. Android provides a static checker veridex [7] for scanning non-SDK interface usages in Android apps. It requires a CSV file hiddenapi-flags.csv, in which APIs are listed along with their blocking policies (e.g., public, conditional blocking). Figure 5 displays an excerpt from the CSV file. Each line corresponds to a specific method or field, i.e., an API. The tags associated with each API specify its blocking policy. For examples, the first line indicates that the field MODE_WORLD_READABLE is public. The second line suggests that the API method canStartActivityForResult() can only be used up to Android 11 (code name red velvet cake). The third line signifies that API Context.destroy() cannot be invoked in any versions. It is important to note that this file only contain bytecode-level signatures, which differ from the TXT list presented in Figure 3. 2.6.1 API Extraction. In the CSV file, each line is a JNI signature of either a method or a field. We extracted their declaring classes from the signatures to obtain the API classes in the CSV list. Also note that, in Android 9 (API-level 28), the non-SDK interfaces were declared in multiple non-CSV files. We simply merge all the files to obtain the CSV list for this Android version. A major difference between the CSV list and other AALs is that the former contains all compiled classes during building Android SDK. Thus, the CSV list involves classes or methods that were synthesized from high-level Java language features. For example, anonymous class and lambda expression are two frontend Java expressions that help developers write concise source code. During compilation, they will be synthesized into some classes or methods. These synthesized APIs are implicitly called in Java bytecode, which
Towards Understanding Android APIs: Official Lists, Vendor Customizations, and Real-World Usage
RQ1: AAL Demographics JAR
XML
RQ2: AAL Inconsistency RQ3: API Existence
TXT
CSV
RQ4: API Usage
Figure 6: Research questions of our empirical study will never be used by Android apps. To filter out these APIs, we adopt some heuristic rules. For example, synthesized APIs typically follow some naming patterns (e.g., postfix Lambda\d+), which can be used to quickly identify them. We also excluded the synthesized class initialization methods [2], which have a special method name <clinit>. On average, these synthesized APIs account for 8.7% of APIs in the CSV lists.
3 Empirical Study 3.1 Research Questions This study focuses on the completeness and correctness of the four AALs. To gain a deeper understanding, we also study the API existence on real Android devices and API usage in real-world Android apps. To drive our study, we raise the following research questions (Figure 6): • RQ1 (AAL Demographics): How many APIs are there in the four AALs? How do they change throughout the evolution of the Android platform? • RQ2 (AAL Inconsistency): What are the differences between APIs included in the four AALs? • RQ3 (API Existence): Do the APIs in AALs really exist on real Android devices? • RQ4 (API Usage): Which APIs in the AALs are commonly used by real-world Android apps? In the subsequent parts, we will provide a detailed explanation of our approach to investigate each RQ and present a thorough discussion of the findings obtained throughout this process.
3.2
AAL Files Collection
Our study relies on authenticated ALLs. To ensure this goal, we directly compiled them from Android source code at the release branches of each Android versions. Specifically, the JAR and XML lists are built from the sdk target and the CSV lists are made with the corresponding build command [6]. The TXT lists can be obtained directly from the specific file directory in the codebase [13]. As non-SDK interfaces restriction was starting from API-level 28, we only collected the four AALs since that. To ensure consistency, we limit our analysis to Android 13 (API-level 33), which is the highest API level supported by our available physical devices (Section 3.5.2).
3.3
RQ1: AAL Demographics
To answer RQ1, we directly counted the numbers of APIs after extraction and preprocessing. Then, we inspected the results and analyzed how each AAL changes along with Android evolution.
EASE 2026, 9–12 June, 2026, Glasgow, Scotland, United Kingdom
The data is present in Table 2. Each row shows the name of the release branch for the given API-level, and the numbers of three types of APIs in the four AALs, respectively. Table 2 shows that the numbers of APIs are mostly increasing during the evolution of the Android platform. For the CSV list, at API-level 29, the number of three APIs increased by more than double. This is because, at API-level 28, the CSV list only contained blocked APIs under three restriction levels. However, starting from API-level 29, this list was expanded to include all bytecode generated from the entire Android framework codebase, including public APIs and whitelist system APIs, etc. As a result, the APIs contained in the list have significantly grown. Note that the CSV list contain a considerably larger number of APIs than the others. We will further investigate its reason in RQ2. However, for the TXT list at API-level 31, the number of classes decreases by 33.9% (= (4742 − 3133)/4742), along with a significant drop in the numbers of fields and methods. Meanwhile, the other AALs still increased their API numbers. This observation suggests that the reduction in API numbers within the TXT list may not attribute to the removal of APIs from the Android framework. Table 3 shows the numbers of added/removed APIs (by pairwise set difference) in the TXT list. At API-level 31, there were 1,807 classes, 6,040 fields and 15,688 methods being removed from the TXT list. Moreover, 6,038 (99.97%) removed fields and 15,682 (99.96%) moved methods come from these removed classes. According to their package names, we aggregated the 1,807 classes and found that 78.1% of them come from either JDK (under package java.* or javax.*) or third-party packages (in org.*). This means, at API-level 31, most non-Android packages were removed from the TXT list, causing a significant drop in the numbers of its including APIs. Finding 1: For AALs under study, the rules governing API inclusion can undergo changes throughout the evolution of the Android platform. Consequently, the number of APIs in AALs may experience significant increases or decreases. For backward-compatibility purpose, Android API removal is carried out carefully [32]. This is also supported by Table 3, such that added APIs are generally more than removed APIs. However, it turns out that APIs removed from AALs can still exist. Taking the 569 removed methods from 32 to 33 in TXT (the last cell in Table 3) as an example. For each method, we search the Android codebase for API-level 32 and 33, and compare its presenting status in both versions. Among them, 547 (96.1%) methods were actually removed from the codebase. For the remaining 22 methods, four of them were labeled by a @removed annotation and became non-SDK interfaces, while the other 18 did not exist in either API-level 32 or 33. An example of the former case is WebSettings.setAppCacheMaxSize(long), which was labeled as deprecated in 32 and later annotated with @removed in its Javadoc string in 33. We successfully invoke this method on a Pixel 3 XL device running Android 13 via Java reflection. This indicates that APIs removed from AALs can still be accessed by apps, posing a soundness challenge to API-based compatibility issue detectors. Finding 2: APIs removed from the AALs may still exist in the Android source code or runtime.
EASE 2026, 9–12 June, 2026, Glasgow, Scotland, United Kingdom
Wang et al.
Table 2: Numbers of Java API in each AAL #Class
#Field
#Method
XML
TXT
CSV
JAR
XML
TXT
CSV
JAR
XML
TXT
CSV
pie-release android10-release android11-release android12-release android12L-release android13-release
28 29 30 31 32 33
4,332 4,530 4,746 5,069 5,075 5,276
4,332 4,526 4,831 5,127 5,133 5,334
4,330 4,526 4,742 3,133 3,139 3,197
10,465 20,013 22,407 26,661 26,847 28,906
22,395 23,396 25,144 26,492 26,545 27,868
22,395 23,396 25,175 26,512 26,565 27,888
22,389 23,396 25,144 20,254 20,307 20,669
70,742 144,518 155,610 179,158 180,796 193,357
44,014 46,242 48,101 50,508 50,550 52,716
35,144 36,931 38,888 40,578 40,603 42,371
38,772 40,389 41,988 27,635 27,662 28,178
63,361 205,333 228,343 262,447 264,074 281,872
:
JAR
:
API
:
:
:
Branch Name
:
:
The symbol indicates the number of API decreases compared to the previous API-level, while means it increases by more than twice.