Android studio导入含有jni代码依赖工程的eclipse项目及常见错误解决

首先,将情景说明清楚:eclipse项目中除了主工程外还有一个依赖工程,且主工程跟依赖工程中都有jni代码,我们应该如何才能正确将其导入android studio且正常编译运行?

下图为eclipse项目结构

其中sample_blur为主工程,CvFaceAPI-jni为依赖工程,都含有jni代码




网上有许多android studio导入eclipse项目的步骤,按照这篇教程来即可,点击打开链接

按照其第二部分的用android studio导入,总结下就是将原project关闭,然后import eclipse项目,选中主工程,根据上文那我们选择导入的就是整个eclipse项目中的sample_blur,android studio会自动将依赖工程也导入



接下来指定好你之后该项目的存放路径

然后在这个地方注意,上面两个选项勾选上,最后一项不要勾选。

最后一项是将module名创建为camelCase风格,camelCase表示首字母小写的驼峰式风格,CamelCase表示首字母大写的驼峰式风格。

不勾选这个选项意味着你原先的工程名是啥样,转换完就是啥样。

18


点击finish等待转换,可能会有下列问题

1.        点击finish后一直处于building“project name”gradle project info

这是因为在线安装gradle包出现问题,解决方法:

查看gradle版本:查看目录C:\Users\用户名\.gradle\wrapper\dists\gradle-1.XX-all

存放位置:C:\Users\用户名\.gradle\wrapper\dists\gradle-1.XX-all\3jdgemv0iv8uqohg3kcp2o88r1\gradle-1.XX-all.zip

知道了版本,知道了位置,剩下的就是在网上下载离线包了,谷歌或者百度搜索gradle-1.XX-all.zip,下载完毕后直接把zip拷贝到C:\Users\用户名\.gradle\wrapper\dists\gradle-1.XX-all\3jdgemv0iv8uqohg3kcp2o88r1\ 下。重启AndroidStudio后,打开项目即可。

(gradle-x.x-all.zip各个版本的离线包集合http://download.csdn.net/album/detail/2265

2.        Could not determine thedependencies of task ':hellojni:compileArmDebugJava'.

> failed to find Build Tools revision 19.0.3

解决方法:这个Build Tools是指“Android SDK Build-tools”,打开SDK Manager勾选对应版本号(比如这里是19.0.3)安装就可以。

3.        项目无法运行,run按钮是灰色的

解决方法:adb环境变量没有配置,只要将adb的路径配置环境变量到path里面就好了

4.        Error: Your project containsC++ files but it is not using a supported native build system


解决方法:

在build.gradle(Module:app) 中添加

sourceSets {

        main {

            jni.srcDirs = []

        }

}

buildTypes{

}

同时添加 android.useDeprecatedNdk=true 在你的 gradle.properties中

jni.srcDirs = []    //这一句是禁用gradle默认的ndk-build,防止AS自己生成android.mk编译jni工程

(sourceSets是用来更改android的默认目录结构)

5.        So动态库无法载入

解决方法:没有对原项目的jni进行编译,依赖工程或者主工程要用到的so都需要编译。根据上面第四点提到的sourceSets,如果想根据eclipse的习惯将so文件放在libs中(android studio默认放在jniLibs中),我们可以在sourceSets的main函数中加入jniLibs.srcDirs = ['src/main/libs']

jniLibs.srcDirs = ['src/main/libs']     //这一句是设置目标的so存放路径,也就是组装到apk中的so路径

如果你的jni代码是在src/main/jni中,还可以设置jni.srcDirs = ['jni']

最后我们在android studio的终端进入到你所需要编译的依赖工程或者主工程的jni目录进行ndk-build,build成功后才会生成我们需要的so文件

这里注意要配置好ndk的环境路径,以及项目所指向的ndk路径是否正确

6.        java.lang.UnsatisfiedLinkError:

com.android.tools.fd.runtime.IncrementalClassLoader$DelegateClassLoadernativeLibraryDirectories=[XXXXXXXXXXXXXXXXXXXXXXXXXXX,/system/arm64]]]couldn't find "libmp3lame.so"

错误问题在于UnsatisfiedLinkError以及后面出现的arm64 couldn’t find  ***.so

我们可以理解为找不到so文件,这里是存放.so的目录有问题,如上面出现的arm64 couldn’t find就是因为没有arm64这个文件夹,只有armeabi和armeabi-v7a,新建arm64文件夹可以编译通过,但还是需要该so能支持64位处理器,否则程序运行也会出错。

arm64-v8a是可以向下兼容的,其下有armeabi-v7aarmeabi armeabi-v7a向下兼容armeabi。对于一个cpuarm64-v8a架构的手机,它运行app时,进入jnilibs去读取库文件时,先看有没有arm64-v8a文件夹;如果没有该文件夹,去找armeabi-v7a文件夹,如果没有,再去找armeabi文件夹,如果连这个文件夹也没有,就抛出异常

如果有arm64-v8a文件夹,那么就去找特定名称的.so文件,注意:如果没有找到,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。

而依赖module引入的so库必须存放在该modle本身的jniLib目录下,而不能放入app Module的库目录中,否则报错。

所以要不就是为依赖module提供可以处理64位处理器的so,要不就除去app module目录下的arm64,依赖module中的结构保持不变,使得系统在加载so库的时候直接到armeabi-v7a中寻找。

7.        Error:

Could not install Gradle distribution from‘https:/ /services.gradle.org/distributions/gradle-2.2.2-all.zip’.

字面意思是现在找不到也安装不了这个版本的gradle

解决方法:先进到Gradle的设置页面 Settings-Build, Execution, Deployment-Gradle

选择用本地的Gradle插件并输入路径


之后还会报错:

Error:(2, 0) No service of type Factoryavailable in ProjectScopeServices.

这个错误点击open file 会跳转到apply plugin: ‘com.github.dcendents.Android-maven’这行。

这时候你需要更新maven-plugin的依赖将这两行代码添加到dependencies{} 依赖标签内

classpath'com.github.dcendents:android-maven-gradle-plugin:1.5'

classpath'com.android.tools.build:gradle:2.2.2'

8.        有时候clean下项目也能解决一些奇奇怪怪的问题

9.        Error:Execution

failed for task':FaceGroupSample:transformNative_libsWithStripDebugSymbolForDebug'. >java.lang.NullPointerException (no error message)

解决方法:空指针异常,说是studio升级到2.2后的Bug

进 local.properties 中把 ndk.dir 直接删除禁用,然后clean–rebuild 就可以了

10.    编译ndk时出现错误

Android NDK: Aborting (set APP_ALLOW_MISSING_DEPS=true toallow missing dependencies)

只需要在jni目录中的android.mk中加入android.useDeprecatedNdk=true

回退ndk版本也可以,但是会失去一些可以使用的函数

11.    Build时出现Failed toresolve: com.google.code.findbugs:jsr305:2.0.1或者

Failed to resolve: junit:junit:4.12等

单纯的网络连接问题。解决办法就是将不需要的library去掉,将以下代码展示的库依赖去掉,重新编译即可将dependencies中下列依赖去掉

compilefileTree(dir: 'libs', include: ['*.jar'])

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',{

    exclude group: 'com.android.support',module: 'support-annotations'

})

testCompile 'junit:junit:4.12'

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

12.     待更新。。。