如何在Android Gradle中添加原生so文件依赖

@author ASCE1885的 Github 简书 微博 CSDN

原文链接

背景

几个月前,基于Google的LevelDB,我为Android平台写了一个名为SnappyDB的键值数据库(NoSQL)。

由于它使用到了原生C++代码,因此最终生成的文件除了Jars包还有so文件。

通过Maven仓库发布我们的函数库没有什么问题(只要你通过繁琐的发布流程),maven-android-plugin可以帮助我们包含共享库。Maven依赖规则使得我们可以指定想要获取的ABI(不同的CPU架构)的类型以及函数库的格式(我们的是.so格式)。

例如,为SnappyDB获取ARM平台共享库:

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

如果你使用的是Maven+Eclipse ADT来构建你的Android应用,使用这个方法没有问题,但如果你将工程迁移到Android Studio+Gradle上,问题就来了。

Android Studio & Gradle

Android的Gradle插件能够很好的处理使用maven仓库的所有的jars依赖(以及其他)。

例如,在build.gradle文件中声明依赖:

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

但是当需要依赖原生函数库时就遇到问题了,类比于Maven,我们不再能够以下面这种方式来加载了:

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

这是因为Android Studio插件对于NDK的支持还做不到这一点。

jniLibs拯救了我们

在Android Studio的0.7.2版本的Android插件中,Google在工程的source sets中引入了一个新的目录‘jniLibs’。这意味着我们可以把预先编译好的.so文件拷贝到这个目录中,之后Android插件就会帮我们将这些原生函数库打包进APK中。

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

这个特性很强大,不过开发者还是需要下载预先编译好的.so文件,并手动拷贝到这个目录中,当我们使用类似Jenkins或者Travis的持续集成系统时就显得不完美了。

已经有很多hacks技巧和解决方法尝试解决这个问题,但很多实际上很繁琐同时要求用户手动下载并拷贝这些原生函数库依赖。

因此,我们需要有更好的解决方案。

android-native-dependencies的引入

android-native-dependencies是我写的一个自动处理查找&下载&拷贝原生函数库依赖到jniLibs目录的Android插件,这样在APK构建过程中可以自动包含这些函数库。

这个插件使用跟声明查找jar包一样的仓库,下面是一个例子:

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 ...
}

规约

DSL artifact遵循Maven artifacts的命名规则。因此,我们下面两种语法都可以使用:

  • 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+‘
}
  • 映射风格
//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+‘
}

在每种语法中,classifier都是可选的。这意味着,当忽略classifier时,插件将会尝试获取所有类型CPU架构(armeabi, armeabi-v7a, x86和mips)的artifacts。

总结

在Android Gradle插件完全支持NDK之前,使用android-native-dependencies可以帮助我们构建CI和自动化原生依赖的重复性的任务。

我同时推荐另一个很棒的由Jake Wharton写的Gradle插件:android-sdk-manager,它可以帮助你下载和管理Android SDK。

文末摄影鉴赏

时间: 2025-01-06 07:11:06

如何在Android Gradle中添加原生so文件依赖的相关文章

如何在Android Studio中添加RecyclerView-v7支持包

1.打开SDK Manager,在Extras树下找到Android Support Library,下载好支持包.RecyclerView在v7-21版本就出来了.我这里不用更新了,说明是最新的,怎么可能不行呢? 2.按照目录结构,在app的build.gradle的dependencies最后添加了一句: compile 'com.android.support:recyclerview-v7:24.2.1' 3.Build——Clean Project.等待Clean完毕后,在Extern

Android Studio-Gradle项目中添加JNI生成文件(.so文件)

当使用gradle时,添加.so和jar包遇到报错: java.lang.UnsatisfiedLinkError: Couldn't load faceppapi: findLibrary returned null 解决办法是将build.gradle写成如下形式: apply plugin: 'android' android { compileSdkVersion 19 buildToolsVersion "19.0.0" defaultConfig { minSdkVersi

如何在Android开发中让你的代码更有效率

如何在Android开发中让你的代码更有效率 最近看了一个视频,名字叫做Doing More With Less: Being a Good Android Citizen,主要是讲如何用少少的几句代码来改善Android App的性能.在这个视频里面,演讲者以一个图片app为例讲解如何应用Android中现有的东西来改善app性能问题. 这个图片app的代码:https://github.com/penkzhou/iogallery.ppt:http://greenrobot.qiniudn.

如何在android studio中cordova的混合开发

基于Android Studio 中Cordova的开发 cordova简介 Cordova的前身是PhoneGap 官网: (http://cordova.io) Cordova应是运行在客户端本地应用容器的web应用.因此,运行在Cordova容器中的Html5应用的结构和传统的基于web服务器的有所不同.传统的web应用中服务器端做了大部分工作,比如按照用户请求传回生成的内容.而Cordova这种容器中的应用本身包括了所需要的静态页面,用户请求一般由js代码响应并与服务器交互,这样与服务器

Android系统中添加一个产品----图文详解

本文本着开源的精神介绍如何向一个Android系统中添加一个产品的整个过程,按照以下过程笔者有理由相信每个将要从事本行业的人都可以完成,其实添加一个产品并不难,难的是对其相关硬件的修改,好了废话不多说. 首先我们要创建一个属于自己产品的目录,这里以WY_device为例,以WY作为产品的名字. 首先从已经存在的产品中拷贝一个以产品的名字为名的.mk文件,修改为自己的.mk文件,在这里为WY.mk 对其进行如下的修改: 然后添加AndroidProducts.mk  这是添加产品的配置文件名路径,

如何在android app中使用STL库

方法: 1.在jni目录下新建Application.mk; 加入 APP_STL := stlport_static右边的值还可以换成下面几个: system - 使用默认最小的C++运行库,这样生成的应用体积小,内存占用小,但部分功能将无法支持 stlport_static - 使用STLport作为静态库,这项是Android开发网极力推荐的 stlport_shared - STLport作为动态库,这个可能产生兼容性和部分低版本的Android固件,目前不推荐使用. gnustl_st

如何在Android Studio中导入SlidingMenu

之前在Eclipse中导入SlidingMenu就弄了很久,最后也成功的导入了. 现在换成用AndroidStudio开发,在导入SlidingMenu的时候就遇到问题了,通过Google终于导入成功,写个随笔,以后忘了可以回来看看 1.首先下载好SlidingMenu 下载地址:https://github.com/jfeinstein10/SlidingMenu 2.把library 复制到 工程中 3.在 settings.gradle中添加 include ':sliding_menu'

【转】如何在 Android 程序中禁止屏幕旋转和重启Activity

原文网址:http://www.cnblogs.com/bluestorm/p/3665890.html 禁止屏幕随手机旋转变化 有时候我们希望让一个程序的界面始终保持在一个方向,不随手机方向旋转而变化:在AndroidManifest.xml的每一个需要禁止转向的Activity配置中加入android:screenOrientation=”landscape” 属性. landscape = 横向portrait = 纵向 避免在转屏时重启Activity android中每次屏幕方向切换时

20170915-如何在jmeter&#39;工具中添加压力机

jmeter中如何添加压力机1.谁的电脑要做压力机们就要把那台电脑的jmeter-server.bat(jmeter的bin文件目录下)启动2.两台电脑要能ping通3.在配置文件中加入这个ip:修改bin/jmeter.properties文件,搜索remote_hosts关键字,在关键字所在行后添加对方电脑的ip,用逗号","分割,末尾加上:默认端口号(#server_port=1099)      例如:remote_hosts=localhost:1099,10.165.124