Restrictions on non-SDK interfaces

Android P introduces new restrictions on the use of non-SDK interfaces, whether directly, via reflection, or via JNI. These restrictions are applied whenever an app references a non-SDK interface or attempts to obtain its handle using reflection or JNI. For more information about this decision, see Improving Stability by Reducing Usage of non-SDK Interfaces.

In general, apps should only use the officially documented parts of the classes in the SDK. In particular, this means that you should not plan to access methods or fields that are not listed in the SDK when you interact with a class via semantics such as reflection.

Using such methods or fields has a high risk of breaking your app.

Differentiating between SDK and non-SDK interfaces

Generally speaking, SDK interfaces are those ones found documented in the Android framework Package Index. Handling of non-SDK interfaces is an implementation detail that the API abstracts away; it is subject to change without notice.

Android P introduces new restrictions on the use of non-SDK interfaces, whether directly, via reflection, or via JNI. These restrictions are applied whenever an app references a non-SDK interface or attempts to obtain its handle using reflection or JNI.

Testing for non-SDK interfaces

You can test your app by downloading the newest version of the Developer Preview of Android P. The Developer Preview prints logs and potentially displays toasts if your app accesses certain, "greylisted" non-SDK interface. If your app calls a "blacklisted" non-SDK interface, the Developer Preview throws an error.

Pay attention to the toasts, which call attention to interfaces that are proposed for restriction. Also, make sure to inspect your app's log messages, which contain more detailed information about the non-SDK interface that your app accessed, including the declaring class, name, and type in the format used by the Android runtime. Log messages also indicate the means of access: direct, via reflection, or via JNI. Last, log messages show whether the called non-SDK interface belongs to the greylist or the blacklist.

You can use adb logcat to access these log messages, which appear under the PID of the running app. For example, an entry in the log might read as follows:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

Greylisted non-SDK interfaces encompass methods and fields which continue to function in Android P, but to which we do not guarantee access in future versions of the platform. If there is a reason that you cannot implement an alternative strategy to a greylisted API, you may file a bug to request reconsideration of the restriction.

Developer Preview 2 moves to a blacklist methods that had been part of a second, "dark" greylist in Developer Preview 1. Blacklisted methods cause apps to throw exceptions as shown in the table in Results of keeping non-SDK interfaces.

Developer Preview 2 also adds StrictMode support for non-SDK interfaces, called detectNonSdkApiUsage, so that when your app calls a greylisted app, the stack trace shows the context.

Results of keeping non-SDK interfaces

The following table provides details about means of access and their respective results.

Means of access Result
Dalvik instruction referencing a field NoSuchFieldError thrown
Dalvik instruction referencing a method NoSuchMethodError thrown
Reflection via Class.getDeclaredField() or Class.getField() NoSuchFieldException thrown
Reflection via Class.getDeclaredMethod(), Class.getMethod() NoSuchMethodException thrown
Reflection via Class.getDeclaredFields(), Class.getFields() Non-SDK members not in results
Reflection via Class.getDeclaredMethods(), Class.getMethods() Non-SDK members not in results
JNI via env->GetFieldID() NULL returned, NoSuchFieldError thrown
JNI via env->GetMethodID() NULL returned, NoSuchMethodError thrown