如何在不公开源代码的情况下使用 gradle 创建 Android Library Jar?
How to create an Android Library Jar with gradle without publicly revealing source code?
我想从一个 Android 库项目中创建一个 Jar。设置方式如下:
|
1
2 3 4 5 6 7 8 9 10 11 |
ProjectName
\- lib | \- lib | \- armeabi | \- libNativeFirst.so | \- libNativeSecond.so \- src \- main \- java \- com.package.sdk \- PackageSDK.java |
我希望将所有这些都打包在一个 Jar 中,但不透露 PackageSDK.java 中存在的源代码。
我这样设置我的 build.gradle 文件:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
buildscript {
repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.5.+' } } apply plugin: 'android-library' repositories { android { defaultConfig { sourceSets { task jar(type: Jar) { |
当我在项目目录中运行 gradlew clean jar 时,会在 ProjectName\build\libs 中创建一个名为 ProjectName.jar 的 Jar 文件。它的结构如下:
|
1
2 3 4 5 6 7 8 9 |
ProjectName.jar
\- lib | \- armeabi | \- libNativeFirst.so | \- libNativeSecond.so \- com \- package \- sdk \- PackageSDK.java |
我希望在执行 jar 任务时包含已编译的 PackageSDK.class 而不是 PackageSDK.java 文件。我可以改变什么来实现这一点?
编辑:
根据 Ben Manes 的建议,我将 sourceSets 的配置更改为以下内容:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
sourceSets {
main { java { srcDir 'src/main/java' } resources { srcDir 'src/../lib' } output { classesDir 'build/classes' resourcesDir 'build/javaResources' } } } |
和jar任务如下:
|
1
2 3 |
task jar(type: Jar) {
from android.sourceSets.main.output } |
Gradle 现在给我这个输出:
Could not find method output() for arguments [build_25r1m0a3etn5cudtt5odlegprd$_run_closure2_closure9_closure10_closure13@138532dc] on source set main.
相关讨论
- 尝试使用 android.sourceSets.main.output 类文件而不是源来构建 jar
- 我应该将 sourceSets { main { output { srcDir '_____' } } } 设置为什么?
- android插件不使用Java插件吗?其中大部分是预先配置的。也许这必须是 output.dirs。查看 Gradle 用户指南
- 我认为它们在某些方面有所不同,但我不能 100% 我用 .dirs 尝试过,但它有同样的问题。我发现我可以只使用 build/bundles/release 中的 classes.jar 文件并将其重命名为 ProjectName.jar,但我希望我不必这样做。
注意:答案已被编辑。请参阅下面的 2014 年 7 月 28 日更新。
这是我最终想出的解决方案。可能有更好的方法可用,但我还没有找到。
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
android {
compileSdkVersion 18 buildToolsVersion"18.0.1" defaultConfig { sourceSets { task clearJar(type: Delete) { task makeJar(type: Copy) { makeJar.dependsOn(clearJar, build) |
运行 gradlew makeJar 在 build/libs 目录中创建一个 ProjectName.jar。这个jar的结构如下:
|
1
2 3 4 5 6 7 8 9 |
ProjectName.jar
\- lib | \- armeabi | \- libNativeFirst.so | \- libNativeSecond.so \- com \- package \- sdk \- PackageSDK.class |
这正是我需要的结果。我现在可以在其他项目中成功使用 ProjectName.jar。
编辑:虽然我可以在 Android Studio 中的项目中使用生成的 jar,但我不能在 ADT 中创建的项目中这样做,因为有关 jar 文件中存在本机代码的警告。据说有一个标志可以关闭此签入设置,但它无法正常工作。因此,如果你想创建一个使用本机代码的库,那些使用 ADT 的人必须手动将 armeabi 目录复制到 libs/.
2014 年 7 月 28 日更新:
从 Android Studio 0.8.0 开始,Gradle 输出目录已更改,上述配置将不起作用。我已将配置更改为以下内容:
|
1
2 3 4 5 6 7 8 9 10 |
task clearJar(type: Delete) {
delete 'build/outputs/ProjectName.jar' } task makeJar(type: Copy) { |
重要提示:请注意,ProjectName.jar 现在将被放入 build/outputs/ 而不是 build/libs/。
相关讨论
- 它在早期版本中工作,但不适用于最新版本的工作室,请您检查并更新。
- @pyus13 我已经通过配置更改更新了答案,以使其与最新的 Android Studio 一起使用
- 太感谢了。但是我仍然很困惑,想知道如果我们自己编写任务,目录为何重要。我知道默认任务(linke apk 生成和所有)的输出目录在 0.8.0 中发生了变化,但是它如何影响我们编写的任务,我只想知道我的知识?
- 就是这样——Gradle 任务在某些目录中移动文件。由于目录已更改,因此需要更新任务以查看正确的任务。否则,一切都差不多。
- 1 以保持此答案是最新的。请继续这样做:)
- @BVB 你能帮我解决我的问题吗? stackoverflow.com/questions/30520314/…
- classes.jar 不是在我的构建目录中创建的,但是类在那里,我可以使用这个命令来启动。任务 jar(类型:Jar){ from('build/intermediates/classes/release')}
- @rlshep,您是否尝试了 2014 年 7 月 28 日更新中的建议?结果如何?
- @BVB 没有创建任何内容。我假设是因为构建目录中没有 classes.jar。
- @rlshep 啊,所以您的构建过程没有创建 build/intermediates/bundles/release/ 目录,只有 build/intermediates/classes/release/?
- @BVB我们可以在项目目录之外的驱动器中的其他地方制作classes.jar吗?
- 理论上你应该可以这样做。修改 makeJar 任务以满足您的需要。您可以在那里指定不同的路径和文件名。
- 看起来这不再适用于 Gradle 4.4,关于如何解决该问题的任何提示?谢谢!
- 抱歉,我没有必要也没有机会尝试更新版本的 Gradle。你看到了什么错误?
只是为@BVB 的答案添加一个轻微的替代方案(尽管很大程度上基于它),这是我必须输出一个 jar myapp-api.jar 的方法,该 jar 用于处理 rest API 交互的纯 Java 项目。它依赖于 Android.jar,因此需要使用 apply plugin: 'com.android.application' 而不仅仅是 apply plugin: 'java'
从 myJavaAPIProject 调用 ./gradlew build jar 来构建和生成 .jar 到 myJavaAPIProject/build/libs/myapp-api.jar
build.gradle
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
//Even though this is a Java project, we need to apply the android plugin otherwise it cannot find the SDK/android.jar and so cannot compile
apply plugin: 'com.android.application' dependencies { repositories { defaultConfig { sourceSets { } //enforce java 7 //Actually created the .jar file |
AndroidManifest.xml
|
1
2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?>
<!-- this is a dummy file needed to ensure gradle validates and builds ok --> <manifest package="com.myapp.android" /> |