- Android NDK Native APIs
- On this page
- Overview
- Major Native API Updates
- Android API level 3
- C library
- C++ library
- Android-specific log support
- ZLib compression library
- Dynamic linker library
- Android API level 4
- OpenGL ES 1.x Library
- Android API level 5
- OpenGL ES 2.0 library:
- Android API level 8
- jnigraphics
- Android API level 9
- OpenSL ES
- Android native application APIs
- Android API level 14
- OpenMAX AL
- OpenSL ES
- Android API level 18
- OpenGL ES 3.0
- Android API level 21
- OpenGL ES 3.1
- Android API Level, backward and forward compatibility
- API Level
- compileSdkVersion
- minSdkVersion
- targetSdkVersion
Android NDK Native APIs
On this page
The Android NDK provides a set of native headers and shared library files that has gradually increased with successive releases of new Android API levels. This page explains these headers and files, and maps them to specific Android API levels.
Overview
There are two basic steps to enable your app to use the libraries that the NDK provides:
- Include in your code the headers associated with the libraries you wish to use.
- Tell the build system that your native module needs to link against the libraries at load time. For example, to link against /system/lib/libfoo.so , add the following line to your Android.mk file:
To list multiple libraries, use a space as a delimiter. For more information about using the LOCAL_LDLIBS variable, see Android.mk.
For all API levels, the build system automatically links the standard C libraries, the standard C++ libraries, real-time extensions, and pthread ; you do not need to include them when defining your LOCAL_LDLIBS variable. For more information about the C and C++ libraries, see Android API level 3.
Table 1 shows the correspondence between NDK-supported API levels and Android releases.
Table 1. NDK-supported API levels and corresponding Android releases.
NDK-supported API level | Android release |
---|---|
3 | 1.5 |
4 | 1.6 |
5 | 2.0 |
8 | 2.2 |
9 | 2.3 through 3.0.x |
12 | 3.1.x |
13 | 3.2 |
14 | 4.0 through 4.0.2 |
15 | 4.0.3 and 4.0.4 |
16 | 4.1 and 4.1.1 |
17 | 4.2 and 4.2.2 |
18 | 4.3 |
19 | 4.4 |
21 | 4.4W and 5.0 |
Each new release of NDK headers and libraries for a given Android API level is cumulative; you are nearly always safe if you use the most recently released headers when building your app. For example, you can use the NDK headers for Android API level 21 for an app targeting API level 16. By doing so, however, you increase your APK’s footprint.
For more information about Android API levels, see What is API Level?.
Major Native API Updates
Android API level 3
The NDK provides the following APIs for developing native code that runs on Android 1.5 system images and above.
C library
The C library headers for Android 1.5 are available through their standard names, such as stdlib.h and stdio.h . If a header is missing at build time, it’s because the header is not available on the 1.5 system image.
C++ library
An extremely minimal C++ support API is available. For more information on C++ library support, see C++ Library Support.
Android-specific log support
You can write your own wrapper macros to access this functionality. If you wish to perform logging, your native module should link to /system/lib/liblog.so . Implement this linking by including the following line in your Android.mk file:
ZLib compression library
You can use the Zlib compression library by including zlib.h and zconf.h . You must also link your native module against /system/lib/libz.so by including the following line in your Android.mk file:
Dynamic linker library
You can access the Android dynamic linker’s dlopen() , dlsym() , and dlclose() functions by including dlfcn.h . You must also link against /system/lib/libdl.so by including the following line in your Android.mk file:
Android API level 4
The NDK provides the following APIs for developing native code that runs on Android 1.6 system images and above.
OpenGL ES 1.x Library
The standard OpenGL ES headers gl.h and glext.h contain the declarations necessary for performing OpenGL ES 1.x rendering calls from native code.
To use these headers, link your native module to /system/lib/libGLESv1_CM.so by including the following line in your Android.mk file:
All Android-based devices support OpenGL ES 1.0, because Android provides an Open GL 1.0-capable software renderer that can be used on devices without GPUs.
Only Android devices that have the necessary GPU fully support OpenGL ES 1.1. An app can query the OpenGL ES version string and extension string to determine whether the current device supports the features it needs. For information on how to perform this query, see the description of glGetString() in the OpenGL specification.
Additionally, you must put a tag in your manifest file to indicate the version of OpenGL ES that your application requires.
The EGL APIs are only available starting from API level 9. You can, however, use the VM to perform some of the operations that you would get from those APIS. These operations include surface creation and flipping. For an example of how to use GLSurfaceView , see Introducing GLSurfaceView.
The san-angeles sample application provides an example of how to perform these operations, rendering each frame in native code. This sample is a small Android port of the excellent San Angeles Observation demo program.
Android API level 5
The NDK provides the following APIs for developing native code that runs on Android 2.0 system images and above.
OpenGL ES 2.0 library:
The standard OpenGL ES 2.0 headers and contain the declarations needed for performing OpenGL ES 2.0 rendering calls from native code. These rendering calls provide the ability to use the GLSL language to define and use vertex and fragment shaders.
To use OpenGL ES 2.0, link your native module to /system/lib/libGLESv2.so by including the following line in your Android.mk file:
Not all devices support OpenGL ES 2.0. An app can query the OpenGL ES version string and extension string to determine whether the current device supports the features it needs. For information on how to perform this query, see the description of glGetString() in the OpenGL specification.
Additionally, you must put a tag in your manifest file to indicate which version of OpenGL ES your application requires. For more information about the OpenGL ES settings for , see OpenGL ES.
The hello-gl2 sample application provies a basic example of how to use OpenGL ES 2.0 with the NDK.
The EGL APIs are only available starting from API level 9. You can, however, use the VM to perform some of the operations that you would get from those APIs. These operations include surface creation and flipping. For an example of how to use GLSurfaceView , see Introducing GLSurfaceView.
Note: The Android emulator does not support OpenGL ES 2.0 hardware emulation. Running and testing code that uses this API requires a real device with hardware that can support OpenGL ES 2.0.
Android API level 8
The NDK provides the following APIs for developing native code that runs on Android 2.2 system images and above.
jnigraphics
The jnigraphics library exposes a C-based interface that allows native code to reliably access the pixel buffers of Java bitmap objects. The workflow for using jnigraphics is as follows:
- Use AndroidBitmap_getInfo() to retrieve information from JNI, such as width and height, about a given bitmap handle.
- Use AndroidBitmap_lockPixels() to lock the pixel buffer and retrieve a pointer to it. Doing so ensures that the pixels do not move until the app calls AndroidBitmap_unlockPixels() .
- In native code, modify the pixel buffer as appropriate for its pixel format, width, and other characteristics.
- Call AndroidBitmap_unlockPixels() to unlock the buffer.
To use jnigraphics , include the header in your source code, and link against jnigraphics by including the following line in your Android.mk file:
Additional details about this feature are in the comments of the bitmap.h file.
Android API level 9
The NDK provides the following APIs for developing native code that runs on Android 2.3 system images and above.
EGL provides a native platform interface for allocating and managing OpenGLES surfaces. For more information about its features, see EGL Native Platform Interface.
EGL allows you to perform the following operations from native code:
- List supported EGL configurations.
- Allocate and release OpenGLES surfaces.
- Swap or flip surfaces.
The following headers provide EGL functionality:
- EGL/egl.h : the main EGL API definitions.
- EGL/eglext.h : EGL extension-related definitions.
To link against the system’s EGL library, add the following line to your Android.mk file:
OpenSL ES
Android native audio handling is based on the Khronos Group OpenSL ES 1.0.1 API.
The standard OpenSL ES headers OpenSLES.h and OpenSLES_Platform.h contain the declarations necessary for performing audio input and output from the native side of Android. The NDK distribution of the OpenSL ES also provides Android-specific extensions. For information about these extensions, see the comments in OpenSLES_Android.h and OpenSLES_AndroidConfiguration.h .
The system library libOpenSLES.so implements the public native audio functions. Link against it by adding the following line to your Android.mk file:
For more information about the OpenSL ES API, refer to $NDK/docs/Additional_library_docs/opensles/index.html , where $NDK is your NDK installation root directory.
Android native application APIs
Starting from API level 9, you can write an entire Android app with native code, without using any Java.
Note: Writing your app in native code is not, in itself, enough for your app to run in the VM. Moreover, your app must still access most features of the Android platform via JNI.
This release provides the following native headers:
For more information about these headers, see the NDK API Reference documentation, as well as the comments in the headers, themselves. Also, for more information about the larger topic of writing native apps, see Native Activities and Applications.
When you include one or more of these headers, you must also link against the libandroid.so library. To link against libandroid.so , include the following line in your Android.mk file:
Android API level 14
The NDK provides the following APIs for developing native code that runs on Android 4.0 system images and above.
OpenMAX AL
Android native multimedia handling is based on Khronos Group OpenMAX AL 1.0.1 API.
The standard OpenMAX AL headers and contain the declarations necessary for performing multimedia output from the native side of Android.
The NDK distribution of OpenMAX AL also provides Android-specific extensions. For information about these extensions, see the comments in OpenMAXAL_Android.h .
The system library libOpenMAXAL.so implements the public native multimedia functions. To link against this library, include the following line in your Android.mk file:
For more information about this topic, see $NDK/docs/openmaxal/index.html , where $NDK is the root directory of your NDK installation.
OpenSL ES
OpenSL ES support for this Android API level adds PCM support. For more information about OpenSL ES support in the NDK, see OpenSL ES.
Android API level 18
The NDK provides the following APIs for developing native code that runs on Android 4.3 system images and above.
OpenGL ES 3.0
The standard OpenGL ES 3.0 headers gl3.h and gl3ext.h contain the declarations needed for performing OpenGL ES 3.0 rendering calls from native code. These rendering calls provide the ability to use the GLSL language to define and use vertex and fragment shaders.
To use OpenGL ES 3.0, link your native module against /system/lib/libGLESv3.so by including the following line in your Android.mk file:
Not all devices support OpenGL ES 3.0. An app can query the OpenGL ES version string and extension string to determine whether the current device supports the features it needs. For information on how to perform this query, see the description of glGetString() in the OpenGL specification.
Additionally, you must put a tag in your manifest file to indicate which version of OpenGL ES your application requires. For more information about the OpenGL ES settings for , see OpenGL ES.
The gles3jni sample application provides a basic example of how to use OpenGL ES 3.0 with the NDK.
Note: The Android emulator does not support OpenGL ES 3.0 hardware emulation. Running and testing code that uses this API requires a real device with hardware that can support OpenGL ES 3.0.
Android API level 21
The NDK provides the following APIs for developing native code that runs on Android 4.3 system images and above.
OpenGL ES 3.1
The standard OpenGL ES 3.1 headers gl31.h and gl3ext.h contain the declarations needed for performing OpenGL ES 3.1 rendering calls from native code. These rendering calls provide the ability to use the GLSL language to define and use vertex and fragment shaders.
To use OpenGL ES 3.1, link your native module against /system/lib/libGLESv3.so by including the following line in your Android.mk file:
Not all devices support OpenGL ES 3.1. An app can query the OpenGL ES version string and extension string to determine whether the current device supports the features it needs. For information on how to perform this query, see the description of glGetString() in the OpenGL specification.
Additionally, you must put a tag in your manifest file to indicate which version of OpenGL ES your application requires. For more information about the OpenGL ES settings for , see OpenGL ES.
The gles3jni sample application provides a basic example of how to use OpenGL ES 3.1 with the NDK.
Note: The Android emulator does not support OpenGL ES 3.1 hardware emulation. Running and testing code that uses this API requires a real device with hardware that can support OpenGL ES 3.1.
Источник
Android API Level, backward and forward compatibility
Jun 9, 2019 · 8 min read
If you get to read this article it might mean you are wondering things like:
- What is an API?
- What does API Level mean?
- How to use compileSdkVersion, minSdkVersionor targetSdkVersion?
- How can I ensure my app will work properly on devices with different versions of the OS?
All these concepts are related to each other and I will try to clarify them to you in this article in a simple but effective way.
In order to do so, we need to have in mind the difference between SDK and API in software development and the meaning of API Level in the Android ecosystem.
In Android, it’s true that th e re is a 1:1 relationship between the SDK and the API and often these two terms are used as synonymous, but it’s important to understand they are not the same thing.
But it’s correct to say that for each Android version there is an SDK and there is an equivalent API and API Level.
It stands for Software Development Kit. Think of the word “kit”… it is exactly a collection or a set of different tools, libraries, documentation, samples to help developers to build, debug and run Android apps. Along with an SDK, an API is provided.
Opening the SDK Manager in Android Studio shows much clearer what is part of an Android SDK.
The first tab SDK Platform lists the SDKs of each Android version.
As per example, shown in the picture below, Android 9.0 (aka Pie) SDK contains:
- Android SDK Platform 28 (that’s the framework API)
- Source code for Android 28 (that’s the implementation of the API, as you can see is optional… keep this in mind)
- and a bunch of other stuff… like different system images for the Android emulator.
The second tab SDK Tools shows a bunch of other tools which are still part of the SDK, but platform version independent, which means they might be released or updated separately.
It stands for Application Programming Interface. It is simply an interface, an abstraction layer that allows communications between two different “pieces” of software. It works as a contract between the provider (e.g. a library) and the consumer (e.g. an app)
It is a set of formal definitions such as classes, methods, functions, modules, constants that can be used by other developers to write their code. Also, an API does not include implementation.
API Level
API Level is an integer value that uniquely identifies the framework API revision offered by a version of the Android platform.
Usually, updates to the framework API are designed so that the new API remains compatible with earlier versions of the API, for this reason, most of the changes to the new API are additive and the old parts of API are deprecated but not removed.
But now someone could argue…
if an Android API doesn’t provide implementation and the SDK Manager offers an optional downloadable API source code as part of the SDK, where is the actual implementation?
The answer is easy. On the device.
Let’s go through this quickly…
From source code to an APK file
Generally, an Android project is composed by the code developers write using Android API (the application module), plus some other libraries/dependencies (.jar, AAR, local modules…etc) and some resources.
The compilation process converts Java/Kotlin code, dependencies included (one reason to shrink your code!), into DEX byte-code and then compressed everything into an APK file along with some resources. At this stage, the implementation of the API is not included in the resulting APK!
DEX files and Android Runtime
The Android Runtime is where all the dirty job is done and where DEX files are executed. It is made of two main components:
- a Virtual Machine in order to take advantages of code portability and platform independence. Starting from Android 5.0 (Lollipop) the old runtime environment, Dalvik Virtual Machine, has been totally replaced by the new Android RunTime (ART). Dalvik used a JIT compiler, whereas ART uses AOT (Ahead of time) compilation plus JIT for runtime code profiling.
- Core Libraries are standard Java libraries and Android libraries. In simple words, this is where the implementation of the API resides.
The API version available at this level is the one offered by the version of the Android platform in which the app is running.
For example, if the actual device has installed Android 9 (Pie), all the APIs until API Level 28 are available.
If the few key concepts of how the Android Runtime works and what is the role of the API is clear so far, then it should be quite easy to understand backward/forward compatibility and the usage of compileSdkVersion, minSdkVersion and targetSdkVersion.
compileSdkVersion
This value is used only to tell Gradle what version of the SDK to compile your app with. For developers, it allows accessing to all the APIs available up to API Level set to compileSdkVersion.
It is strongly recommended to compile against the latest SDK version:
- a high API Level allows developers to take advantages of the latest APIs and capabilities provided by new platforms.
- in order to use the latest SupportLibrary, compileSdkVersion has to match the SupportLibrary version too.
For example, in order to use SupportLibrary-28.x.x, compileSdkVersion has to be set to 28 as well. - for migrating to/using AndroidX, compileSdkVersion has to be set at 28 at least.
- getting ready to satisfy Google Play’s target API level requirement. As announced by Google, in order to spread new Android versions quicker out in the market, every year Google will enforce a minimum target API Level for new applications and updates. More info here and here.
Android applications are forward-compatible with new versions of the Android platform because API changes are generally additive and old APIs might be deprecated, but not removed.
That means forward compatibility is basically guaranteed by the platform and running an application on a device with a higher API Level than the one specified in compileSdkVersion does not have any runtime issue, the application runs as expected on newer platform versions too.
App + compileSdkVersion = 26 and using an API xyz() introduced in API Level 26 can run on a device with Android 8 Oreo (API Level 26).
The same app can run on a device with Android 9 Pie (API Level 28) since the API xyz() is still available in API Level 28 .
minSdkVersion
This value specifies the minimum API Level in which the application is able to run. It’s the minimum requirement. If not specified, the default value is 1.
It is developers responsibility to set a proper value and ensure the application runs properly down to this API Level. This is called backward compatibility.
During development, Lint will also warn developers when trying to use any API above the specified minSdkVersion. It is really important to not ignore these warnings and fix them!
In order to provide backward compatibility, developers can check at runtime the platform version and use a new API on newer versions of the platform and old API on older versions or, depending on the case, using some static libraries which offer backward compatibility.
It is also important to mention Google Play Store uses this value to determinate if an app can be installed on a specific device by matching the device platform version with the app minSdkVersion.
Developers should be really careful when picking this value since backward compatibility is not guaranteed by the platform.
Picking a “right” value for a project is also a business decision since it affects how big is the audience the application is made for. Have a look at the platform distribution.
For example:
App + compileSdkVersion = 26 + minSdkVersion = 22 and using an API xyz() introduced in API Level 26 can run on a device with Android 8 Oreo (API Level 26).
The same app can be installed and run on an older device with Android 5.1 Lollipop (API Level 22), where the API xyz() does not exist. If no backward compatibility has been provided by developers either with runtime checks or some sort of libraries, then the application will crash as soon as it tries to access the API xyz().
targetSdkVersion
This value specifies the API Level on which the application is designed to run.
It doesn’t have to be confused with compileSdkVersion. The latter is only used at compile time and it makes new APIs available to developers. The former, instead, is part of the APK (as well as the minSdkVersion) and changes runtime behavior. It is the way developers can control forward compatibility.
Sometimes there might be some API changes on the underlying system that can affect how an application behaves when is running on a new runtime environment.
Targeting an application to a specific version enables all of those system runtime behaviors, which are dependent on that specific version of the platform. If an app is not ready to support these runtime behavior changes it is likely going to crash.
A simple example is the Runtime Permission, which has been introduced with Android 6 Marshmallow (API Level 23).
It is possible for an application to compile against API Level 23, but targeting API Level 22 if it is not ready yet to adopt the new runtime permission model.
In this way, an application can still be forward compatible without enabling the new runtime behavior.
Anyway, as already mentioned Google is enforcing apps to satisfy new target API level requirements, so it should be a high priority to always update this value.
Putting all together at the end there is a clear relationship
Keep in mind it is highly recommended to compile against the latest API Level and try to have targetSdkVersion == compileSdkVersion.
Источник