Skip to main content
Bionic is Android’s C library, math library, and dynamic linker. Understanding bionic’s characteristics and differences from standard C libraries like glibc is essential for writing portable and compatible NDK code.

What is bionic?

Bionic is Android’s implementation of the C standard library, providing:
  • Standard C library functions: malloc, printf, file I/O, etc.
  • POSIX APIs: Threading, sockets, file operations
  • Math library (libm): Mathematical functions
  • Dynamic linker: Loads shared libraries at runtime
  • Android-specific extensions: Additional APIs for Android platform integration
Bionic is BSD-licensed (not GPL), which aligns with Android’s licensing requirements and allows broader use in proprietary code.

Why bionic exists

Android created bionic instead of using existing C libraries for several reasons:
  • BSD license instead of GPL (glibc’s license)
  • Allows proprietary code without GPL restrictions
  • More flexible for device manufacturers and app developers
  • Smaller memory footprint than glibc
  • Critical for resource-constrained mobile devices
  • Stripped-down implementation focused on Android needs
  • Original glibc: ~2-3 MB, bionic: ~500-800 KB
  • Optimized for ARM processors (primary Android architecture)
  • Fast thread-local storage (TLS)
  • Efficient memory allocator for mobile workloads
  • Support for Android-specific kernel features
  • Built-in FORTIFY_SOURCE protections
  • Stack canaries and buffer overflow detection
  • Secure random number generation
  • Modern security features from the ground up

Key differences from glibc

Understanding these differences helps avoid portability issues:

Missing or limited functionality

Bionic intentionally omits some glibc features:
Before Android 5.0 (API 21), locale support was extremely limited. From API 21+, ICU4C provides comprehensive internationalization support.
Solution: Use ICU4C for internationalization:

Implementation differences

Some functions exist but behave differently than glibc:

API levels and compatibility

Bionic evolves with Android versions. Functions are added and behavior changes across API levels:

Understanding API levels

Each Android version has an API level:
Your app’s minSdkVersion determines which APIs you can use. Features from higher API levels won’t be available on older devices.

Major API level milestones

Key bionic improvements by API level:
Major improvements:
  • 64-bit support (arm64-v8a, x86_64)
  • Significantly improved locale support via ICU
  • Full C11 threading support
  • Position-independent executables (PIE) required
API 21 is often considered the minimum for modern NDK development due to 64-bit and improved standards compliance.
Major changes:
  • Runtime permissions affect file access
  • Better FORTIFY_SOURCE protections
  • Enhanced DNS resolution
Major changes:
  • Private API restrictions begin
  • Cannot use non-public symbols from platform libraries
  • File-based encryption affects file paths
Starting in API 24, directly linking against private platform libraries (like libandroid_runtime.so) is restricted. Use only public NDK APIs.
Major restrictions:
  • Strict enforcement of public API access
  • Gray-list restrictions on non-SDK interfaces
  • Enhanced stack protections
Features:
  • Neural Networks API 1.2
  • Scoped storage affects file access
  • APEX modularization (bionic can be updated independently)
Ongoing improvements:
  • Continued security hardening
  • New standard library features
  • Performance optimizations
  • Regular bionic updates via APEX

Standard library support

Bionic supports most C and C++ standards:

C standard library

Fully supported (all API levels):

C++ standard library

Bionic works with libc++ (LLVM’s C++ standard library):
The NDK uses libc++ (LLVM’s C++ library), not GNU libstdc++. This is important for C++ ABI compatibility.

Common compatibility issues

Using conditionals for API availability

Handling missing functions

Weak linking for optional features

Best practices

Set appropriate minSdkVersion

Recommended minSdkVersion: API 21 (Android 5.0)
  • Covers 99%+ of active devices (as of 2024)
  • 64-bit support
  • Better standards compliance
  • Modern security features

Check bionic status documentation

For definitive API availability, consult:

Use feature detection

Avoid private APIs

Never use symbols not in the public NDK API. They may:
  • Disappear in future Android versions
  • Behave differently across devices
  • Cause your app to be rejected or break

Testing across API levels

Ensure compatibility by testing on multiple Android versions:

Resources

For more information on bionic:

Next steps

When in doubt about API availability, compile with the lowest minSdkVersion you support and test on actual devices running that Android version.