首先,这是我在Eclipse中的Java构建路径:
这四个jar的common.jar,core.jar,framework.jar,layout.jar'是从Android源代码打包的,其中包含一些开发人员无法公开使用的类。他们不必是导出因为它们是作弊编译器。在Eclipse中一切都很好。
现在我正在尝试使用gradle将我的项目导入Android-Studio。我已经将jar添加到依赖项中,但是我无法更改我的jar和android jar的编译顺序。我不能把这些罐放在android jar前面。我不熟悉gradle,现在编译器无法在这些jar中找到类。任何帮助将不胜感激! 这是我的build.gradle:
apply plugin: 'android'
dependencies {
compile files('jars/common.jar')
compile files('jars/core.jar')
compile files('jars/framework.jar')
compile files('jars/layout.jar')
compile fileTree(dir: 'libs', include: '*.jar')
compile files('jars/animation_nineoldandroids_src.jar')
compile files('jars/json_simple_src.jar')
compile files('jars/jsoup-1.7.2-sources.jar')
}
android {
compileSdkVersion 17
buildToolsVersion "21.1.1"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests')
// Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}
答案 0 :(得分:10)
你不能在Gradle(*)中做你想做的事,至少在写这篇文章时的可预见的未来。一些问题妨碍你:
android.jar
之前的做法。 Gradle的理念是你应该明确你的构建中的依赖关系,这样才能理解和重复。依赖类路径排序的系统往往是微妙和脆弱的。因此,您需要做的是告诉Gradle您的项目取决于您的自定义类而不是android.jar
,但插件的DSL并没有为您提供这样做的方法。在http://forums.gradle.org/gradle/topics/classpath_ordering_again和http://www.gradle.org/docs/current/userguide/dependency_management.html android.jar
的引用被硬编码到Android Gradle插件中,因此您无法获得该依赖项并将其替换为其他内容。(*)说完了这一切,没有什么是不可能的 - 你可以让它发挥作用,但你必须要一起破解某些东西,所以它会比它更容易出问题Eclipse方法,面对SDK和工具更新更难以维护。当出现问题时,你将自己独立。
android.jar
组合自己的自定义SDK。 我对这些方法中的任何一种都提供了更多的洞察力,部分原因是我不太了解它并且很容易给你不好的建议,部分是因为我不想要没有经验的开发人员看到这一点认为这是一件很棒的事情。但是如果你弄明白的话,那将是非常值得写的,因为我之前已经看过这样的问题,所以你并不是唯一的问题。
答案 1 :(得分:10)
以下脚本适用于我:
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xbootclasspath/p:/mylib.jar')
}
}
}
答案 2 :(得分:8)
我从this post解决了使用系统库构建应用程序的问题:
假设您在libframework.jar
中添加了libcore.jar
和app/libs
等系统库:
将Xbootclasspath
添加到您的顶级build.gradle
:
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xbootclasspath/p:app/libs/libframework.jar:app/libs/libcore.jar')
}
}
}
build.gradle
中,请使用provided
:
dependencies {
provided fileTree(include: ['*.jar'], dir: 'libs')
}
在同一个应用build.gradle
中,添加一个任务,将<orderEntry>
引用Android API 25 Platform
放在app.iml
的最后一个位置,这样gradle会考虑到首先考虑您的系统库和最后的Android SDK:
preBuild {
doLast {
def imlFile = file(project.name + ".iml")
println 'Change ' + project.name + '.iml order'
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.substring("android-".length()) + " Platform"
new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (FileNotFoundException e) {
// nop, iml not found
}
}
}
答案 3 :(得分:0)
您可以自动执行此操作,就像在Eclipse中一样:
File
&gt; Project structure...
&gt; (select app in Modules)
&gt; (go to Dependencies tab)
&gt; reposition with arrows on the right
另一种方法是编辑应用程序所在文件夹中的[AppName] .iml文件。您要更改的是文件末尾的标记。但是,每次清理或重新打开项目时,Android Studio都会重新排列这些内容。
答案 4 :(得分:0)
...
dependencies {
provided files("$projectDir/exlibs/yourlib.jar")
}
答案 5 :(得分:0)
我使用以下场景,完美的解决方案!
XXX.jar
添加到资料库在项目.gradle
中找到此内容:
allprojects {
repositories {
jcenter()
}
}
将其更改为:
allprojects {
repositories {
jcenter()
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\XXX.jar')
}
}
}
在YourApplicationName.iml
文件中,将XXX.jar
调整为顶部,例如this
所以,没关系!
答案 6 :(得分:0)
将app / app.iml文件订单更新为
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="common" level="project" />
<orderEntry type="library" exported="" name="framework" level="project" />
<orderEntry type="library" exported="" name="layout" level="project" />
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
答案 7 :(得分:0)
对我来说,最简单的解决方案是将android.jar
替换为包含隐藏API的android.jar
。从此项目library that provides access to Android hidden API and internal resources获取compileSdkVersion
并将其放入您的ASDK平台文件夹,以及您正在编译的平台(uint32_t mod_add(uint32_t x, uint32_t y, uint32_t n)
{
uint32_t res;
res = (x + y) % n;
)。
我确信它也适用于Eclipse))
答案 8 :(得分:0)
一个更新的,更符合未来发展的答案(因为在最近的JDK中bootclasspath编译器args有所更改):
dependencies {
compileOnly fileTree(dir: 'system_libs', include: ['*.jar'])
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.bootstrapClasspath = files(
new File("./system_libs/framework.jar").path,
new File("./system_libs/libcore.jar").path
)
}
}
将指向Android API平台的任务添加到app.iml中的最后一个位置,这样gradle将首先考虑系统库,最后考虑Android SDK:
preBuild {
doLast {
def imlFile = file(project.name + ".iml")
println 'Change ' + project.name + '.iml order'
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.substring("android-".length()) + " Platform"
new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (FileNotFoundException e) {
// nop, iml not found
}
}
}
基于@Bertrand的答案
答案 9 :(得分:0)
这真的很简单!
而且您无需再修改项目中的 build.gradle
!
第 1 步:
在Android-SDK目录下备份你原来的android.jar(例如你的应用compileSdkVersion=30
在build.gradle
中,对应的路径是“~/Library/Android/sdk /platforms/android-30”(在 MacOS 上)。
第 2 步: 将您的自定义 framework.jar(*) 重命名为“android.jar”并将其复制到您的 Android-SDK 目录中,与原始目录相反。
第 3 步: 如果需要,同步 gradle,然后你可以使用你想要的@hide 函数而不会报告红色错误。
(*) 如果你不想花时间克隆 AOSP 并编译它,你最好在 Github 上下载它:https://github.com/anggrayudi/android-hidden-api
祝你好运~
答案 10 :(得分:0)
似乎*.impl
文件路径已经改变,你需要改变
def imlFile = file(project.name + ".iml")
与
def imlFile = file(".." + File.separator + ".idea" + File.separator + "modules" + File.separator + project.name + File.separator + rootProject.name + "." + project.name + ".iml")