首先,将情景说明清楚: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表示首字母大写的驼峰式风格。
不勾选这个选项意味着你原先的工程名是啥样,转换完就是啥样。
点击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-v7a,armeabi ;armeabi-v7a向下兼容armeabi。对于一个cpu是arm64-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. 待更新。。。