这几天工作上遇到一个问题,三方的jar包在liunx下解压不了,用gradle又能正常编译,我们的apk是在liunx下用mk进行编译的,编译的过程中需要对jar包进行解压,这样就导致编译失败。
错误信息如下:以后再遇到这个错误,可能就jar包的问题。
FAILED: /bin/bash -c "(mkdir -p out/target/common/obj/JAVA_LIBRARIES/xxx-sdk_intermediates/classes.jack.tmpjill.res ) && (unzip -qo /home/x/xx/xxx/APK92_GNBJ_EDO/code/libs/xxx-sdk-java20171027120314.jar -d out/target/common/obj/JAVA_LIBRARIES/xxx-sdk_intermediates/classes.jack.tmpjill.res ) && (find out/target/common/obj/JAVA_LIBRARIES/xxx-sdk_intermediates/classes.jack.tmpjill.res -iname \"*.class\" -delete ) && (JACK_VERSION=3.36.CANDIDATE out/host/linux-x86/bin/jack @build/core/jack-default.args --verbose error -D jack.import.resource.policy=keep-first -D jack.import.type.policy=keep-first -D jack.android.min-api-level=1 --import /home/x/xx/xxx/APK92_GNBJ_EDO/code/libs/xxx-sdk-java20171027120314.jar --import-resource out/target/common/obj/JAVA_LIBRARIES/xxx-sdk_intermediates/classes.jack.tmpjill.res --output-jack out/target/common/obj/JAVA_LIBRARIES/xxx-sdk_intermediates/classes.jack ) && (rm -rf out/target/common/obj/JAVA_LIBRARIES/xxx-sdk_intermediates/classes.jack.tmpjill.res )" warning: stripped absolute path spec from / mapname: conversion of failed ninja: build stopped: subcommand failed. build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed
解决方法:对jar包源码重新打包
1.gradle命令解压jar包源码
解压jar包源码,注意,是带源码的jar包,如果是编译过的jar,是不能重新打包的。
步骤:
1.新建build.gradle文件,因为gradle会默认找到当前目录下的build.gradle下的文件去执行;
2.在终端执行gradle unzip,执行这个task
以下命令将这个目录app/libs/xxx-sdk-java20171027120314.jar
下的jar包解压到了unpacked/dist
目录。
apply plugin: 'java'
sourceCompatibility = 1.7
targetCompatibility = 1.7
// 解压缩第三方jar包到某目录
task unzip(type: Copy) {
// 原始jar包文件
def zipFile = file('app/libs/xxx-sdk-java20171027120314.jar')
// 解压缩目标目录
def outputDir = file("unpacked/dist")
// 文件过滤,去除部分class。这里建议写精确点,因为可能存在名称相同或相近的文件。
FileTree jarTree = zipTree(zipFile)
// 从jar的目录树中输出到目标目录
from jarTree
into outputDir
}
2. 将源码重新打jar包
解压之后的源码就是文件夹,重新打包的时候需要注意,包名和源码的路径名一致。现在利用Android studio进行打包。
步骤:
1.新建lib module,选择Android Libeary/Java Library;
2.注意修改包名与jar包路径相同,eg:jar包解压之后的路径dist/com/example/api
,那么为了确保新生成的jar包里的Java文件import路径相同,module的包名也要命名为com.example.api
;
3.将解压之后的源码java文件复制到lib model中;
4.在app module
下添加lib module
依赖。这是一种取巧的方法,当你添加了lib module依赖之后,项目会重新rebuild,这个过程会将module依赖编译成jar包,存放在lib module的build/libs
目录下,由于Android Studio版本不同,这个目录可能有有所不同,但是都在build目录下,找新的jar包就可以了。
这一部可能会报jar包找不到,或者lib module中的import失败,可能是因为lib module依赖的jar包没导入,导入之后在lib module的build.gradle里配置一下就可以了。
//配置lib module依赖的jar包:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
这个时候,其实直接用这个jar包也可以了,如果向修改jar包名字,可以执行下面的gradle命令:
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
task makeJar(type: Copy) {
//删除存在的
delete 'build/libs/alipaysdk.jar'
//设置拷贝的文件
from('build/libs/')
//打进jar包后的文件目录
into('libs/')
//将classes.jar放入build/libs/目录下
//include ,exclude参数来设置过滤
//(我们只关心classes.jar这个文件)
include('lib.jar')
//重命名
rename ('lib.jar', 'alipaysdk.jar')
}
makeJar.dependsOn(build)
想了解更多可以参考这里
然后在项目里测试一下jar包就可以了。
重新打包之后就可以在liunx下解压了,正常编译通过。
总结
最后记录一下mk编译的一个错误# [ERROR: Dex writing phase: classes.dex has too many IDs. Try using multi-dex](https://stackoverflow.com/questions/45472852/error-dex-writing-phase-classes-dex-has-too-many-ids-try-using-multi-dex)
在stackoverflow上找到了解决方法。
在mk文件中添加
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
LOCAL_JACK_FLAGS += --multi-dex native
参考:
https://stackoverflow.com/questions/39457116/gradle-build-hanging-when-jackoptions-is-enabled-for-java-1-8
https://stackoverflow.com/questions/45472852/error-dex-writing-phase-classes-dex-has-too-many-ids-try-using-multi-dex