问题背景
在系统开发中,需要直接依赖framework.jar ,而工程会优先使用Android sdk,导致调用jar包中特有的方法会报错
解决方法
- libs中放入对应的framework.jar ,并在module的build.gradle中加入依赖,这里是compileOnly
compileOnly files('libs/framework.jar')
- 修改 jar包的依赖顺序
// scan first android.p.framework.jar when JavaCompile
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
// android studio 3.X 的版本只需要加入第一句代码
options.compilerArgs.add('-Xbootclasspath/p:libs/framework.jar')
// android studio 4.X 的版本需要以下代码
Set<File> fileSet = options.bootstrapClasspath.getFiles()
List<File> newFileList = new ArrayList<>()
newFileList.add(new File("./libs/framework.jar"))
newFileList.addAll(fileSet)
options.bootstrapClasspath = files(newFileList.toArray())
}
}
- 配置前两步,此时已经可以正常build ,且可以打出apk,但是IDE在相关方法会报警,提示红色错误,需要继续以下处理,
def getTargetFile() {
def pathRoot = file("../../" + rootProject.name + "/.idea/modules")
def targetFileName = rootProject.name + "." + project.name + ".iml"
def targetFilePath
println 'targetPath ' + pathRoot.absolutePath + ";" + targetFileName
pathRoot.listFiles().each { x ->
def dir = x.isDirectory()
if (dir) {
x.listFiles().each {
def setting = it.path.contains(targetFileName)
println 'targetPath x.isDirectory() .listFiles() ' + setting + ";" + it.absolutePath
if (setting) {
targetFilePath = it.absolutePath
return targetFilePath
}
}
}
}
return targetFilePath
}
preBuild {
doLast {
def targetPath = getTargetFile()
println 'targetPath ' + targetPath
def imlFile = file(targetPath)
try {
def parsedXml = (new XmlParser()).parse(imlFile)
def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
parsedXml.component[1].remove(jdkNode)
def sdkString = "Android API " + android.compileSdkVersion + " Platform"
new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (Exception e) {
println 'Change .iml order error'
}
}
}
此时需要sync,再次build,IDE已经没有告警
可能的问题解决方法
如果经过以上三步还是不行,可能是framework.jar 的jdk版本和IDE设置的jdk版本不一致,修改工程的jdk版本为jdk8或者jdk11,重新尝试