DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Understanding Dependencies...Visually!
  • How To Approach Dependency Management in Java [Video]
  • Is It Okay To Stop Running Your Tests After the First Failure?
  • HTML5 on Android 4.0: Way Better, Still Behind iOS 5

Trending

  • Build a Serverless App Fast With Zipper: Write TypeScript, Offload Everything Else
  • Spring WebFlux Retries
  • Log Analysis Using grep
  • Software Verification and Validation With Simple Examples
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Android Gradle: Add Native .so Dependencies

Android Gradle: Add Native .so Dependencies

Maven dependencies convention allows you to specify the type of ABI and the format of the library you want to resolve using classifier.

Nabil Hachicha user avatar by
Nabil Hachicha
·
Jun. 04, 14 · Tutorial
Like (1)
Save
Tweet
Share
35.15K Views

Join the DZone community and get the full member experience.

Join For Free

Background 

A few months ago, I wrote a Key-Value database for Android called SnappyDB based on Google’s LevelDB.  Since it uses native C++ code, the generated bundle contains (.so) binaries libs, along with Jars. 

Distribution via Maven repo is not a problem (As soon as you pass the hassle of the publishing process:), maven-android-plugin can help you include the shared libs. Maven dependencies convention allows you to specify the type of ABI (different CPU architectures) & the format of the library (obviously .so in our case) you want to resolve using classifier: 

Ex: resolving ARM shared lib for SnappyDB:

<dependency>
  <groupId>com.snappydb</groupId>
  <artifactId>snappydb-native</artifactId>
  <version>0.2.0</version>
  <classifier>armeabi</classifier>
  <type>so</type>
</dependency>

This approach works fine if you use Maven & Eclipse ADT as a build system, until you succumbed to Gradle’s siren call! 

Android Studio & Gradle 

Android Gradle plugin, handle gracefully all Jars dependencies by using maven repos (among others …) 

ex: declaring a dependency inside build.gradle

dependencies {
     classpath 'commons-io:commons-io:2.4'
}

but it struggles when it comes to native dependencies, as compared with Maven, you can’t¹ write something like this:

dependencies {
       classpath 'com.snappydb:snappydb-native:2.+:arm-v7a'
}

This is due to the fact that the NDK support is still a work in progress with Android plugin. (as with Android Studio).

 ¹ actually, technically speaking you can, but Gradle will just ignore these native file since it doesn’t know what to do with them.

jniLibs to the rescue!

In their 0.7.2  release of the Android plugin, Google introduced a new folder ‘jniLibs‘ to the source sets. This means, that you can now add your prebuilt .so files to this folder, and Android plugin will take care of packaging those native libraries inside your APK.

.
├── AndroidManifest.xml
└── jniLibs
    ├── armeabi
    │   └── libsnappydb-native.so
    ├── armeabi-v7a
    │   └── libsnappydb-native.so
    ├── mips
    │   └── libsnappydb-native.so
    └── x86
        └── libsnappydb-native.so

This feature is great, but the developer still need to download & copy his prebuilt .so files manually, which isn’t great especially if you use a Continuous Integration server like Jenkins or Travis for instance. 

A lot of hacks & workarounds  emerged to try to sort this out, but a lot of them are really verbose & require the user to download manually his native dependencies. 

So, you get the picture. There has to be a better way.

Meet android-native-dependencies

android-native-dependenciesis a Gradle plugin I wrote to automate the process of resolving & downloading & copying the native dependencies into jniLibs folder, so Android plugin can include them automatically in your APK build. 

The plugin uses the same repository declared to resolve regular dependencies (jar) here is an example:

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:0.10.+'
    classpath 'com.nabilhachicha:android-native-dependencies:0.1'
  }
}

apply plugin: 'android'
apply plugin: 'android-native-dependencies'

native_dependencies {
    artifact 'com.snappydb:snappydb-native:0.2+:armeabi'
    artifact 'com.snappydb:snappydb-native:0.2+:x86'
}

dependencies {
    //regular Jar dependencies ...
}

Convention

The artifact DSL follows the naming convention for Maven artifacts. thus, you can use one of the following syntax: 

  • abbreviated group:name:version[:classifier]
//adding x86 classifier will resolve only intel's (.so) lib
native_dependencies {
    artifact 'com.snappydb:snappydb-native:0.2+:x86'
}

//omit the classifier will resolve all supported architectures
native_dependencies {
    artifact 'com.snappydb:snappydb-native:0.2+'
}
  • map-style notation
//adding x86 classifier will resolve only intel's (.so) lib
native_dependencies {
    artifact group: 'com.snappydb', name: 'snappydb-native', version: '0.2+', classifier: 'x86'
}

//omit the classifier will resolve all supported architectures
native_dependencies {
    artifact group: 'com.snappydb', name: 'snappydb-native', version: '0.2+'
}

In both notations, classifier is optional. this means that when omitted, the plugin try to resolve the artifacts for all architectures: armeabi, armeabi-v7a, x86 and mips. 

Conclusion

Until we get a full support for NDK in Android Gradle plugin, using android-native-dependencies can help you build your CI & automate repetitive task with native dependencies. Please try it and send your feedback to @nabilhachicha . 

Another great Gradle plugin I recommend is the android-sdk-manager  by (Jake Wharton) who helps downloads and manages your Android SDK.

Android (robot) Dependency Gradle

Opinions expressed by DZone contributors are their own.

Related

  • Understanding Dependencies...Visually!
  • How To Approach Dependency Management in Java [Video]
  • Is It Okay To Stop Running Your Tests After the First Failure?
  • HTML5 on Android 4.0: Way Better, Still Behind iOS 5

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: