Выпуск JAR библиотеки Android Gradle

Как я могу выпустить Jar-пакет проекта android-library?
Я обнаружил, что classes.jar находится в build/bundles/release/classes.jar, и я полагаю, что это правильный пакет Jar (содержит *.class файлы).

Есть ли какой-нибудь официальный способ выпустить библиотеку как JAR вместо AAR?

Изменить
Я использую Gradle для выпуска артефактов Maven, и я хотел бы выпустить JAR вместе с пакетом AAR. Итак, JAR с подписью, md5, manifest, ...
на основе https://chris.banes.me/2013/08/27/pushing-aars-to-maven-central/

apply plugin: 'maven'
apply plugin: 'signing'

configurations {
    archives {
        extendsFrom configurations.default
    }
}

def sonatypeRepositoryUrl
if (isReleaseBuild()) {
    println 'RELEASE BUILD'
    sonatypeRepositoryUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
} else {
    println 'DEBUG BUILD'
    sonatypeRepositoryUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
}

if(!hasProperty('nexusPassword')) {
    ext.set('nexusPassword', System.console().readPassword("\n\$ Type in password for Sonatype nexus account " + nexusUsername + ": "))
}

if(!signing.hasProperty('password')) {
    ext.set('signing.password', System.console().readPassword("\n\$ Type in GPG key password: "))
}

afterEvaluate { project ->
    uploadArchives {
        repositories {
            mavenDeployer {
                beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }

                pom.artifactId = POM_ARTIFACT_ID

                repository(url: sonatypeRepositoryUrl) {
                    authentication(userName: nexusUsername, password: nexusPassword)
                }

                pom.project {
                    name POM_NAME
                    packaging POM_PACKAGING
                    description POM_DESCRIPTION
                    url POM_URL

                    scm {
                        url POM_SCM_URL
                        connection POM_SCM_CONNECTION
                        developerConnection POM_SCM_DEV_CONNECTION
                    }

                    licenses {
                        license {
                            name POM_LICENCE_NAME
                            url POM_LICENCE_URL
                            distribution POM_LICENCE_DIST
                        }
                    }

                    developers {
                        developer {
                            id "loopj"
                            name "James Smith"
                        }
                        developer {
                            id "smarek"
                            name "Marek Sebera"
                        }
                    }
                }
            }
        }
    }

    signing {
        required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
        sign configurations.archives
    }

    task androidJavadocs(type: Javadoc) {
        source = android.sourceSets.main.java.srcDirs
    }

    task androidJavadocsJar(type: Jar) {
        classifier = 'javadoc'
        from androidJavadocs.destinationDir
    }

    task androidSourcesJar(type: Jar) {
        classifier = 'sources'
        from android.sourceSets.main.java.srcDirs
    }

    artifacts {
        archives androidSourcesJar
        archives androidJavadocsJar
    }
}

с использованием

task androidJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
}

будет упаковывать только файлы java, не скомпилированные и не связанные с android sdk


person Marek Sebera    schedule 10.10.2013    source источник


Ответы (3)


Хотя я не пробовал загружать артефакты с развертыванием в Sonatype (или даже в локальное хранилище), вот что мне удалось придумать: несколько недель назад при попытке решить ту же проблему.

android.libraryVariants.all { variant ->
  def name = variant.buildType.name
  if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
    return; // Skip debug builds.
  }
  def task = project.tasks.create "jar${name.capitalize()}", Jar
  task.dependsOn variant.javaCompile
  task.from variant.javaCompile.destinationDir
  artifacts.add('archives', task);
}

Затем запустите следующее:

./gradlew jarRelease
person Jake Wharton    schedule 20.10.2013
comment
Боюсь, это правильный ответ :-) Спасибо, я опубликую последнюю правку, которую я сделал, чтобы заставить ее работать - person Marek Sebera; 22.10.2013
comment
Я также могу подтвердить, что это работает. Обратите внимание, что созданная задача не отображается при запуске gradle tasks, только с gradle tasks --all. Спасибо еще раз! - person CommonsWare; 03.12.2013
comment
Спасибо, это действительно помогает, но по-прежнему не генерирует файлы классов для зависимостей. Я пытаюсь создать банку SDK в основном, которая будет одной банкой для передачи, но эта компиляция не включает проекты модулей, от которых она зависит, и не извлекает банки из раздела зависимостей и т. Д. Есть ли у вас какие-либо проекты предложения по достижению этого, где он также компилирует проекты библиотеки в jar, поэтому мне не нужно раздавать 4 jar-файла, по одному для каждого проекта библиотеки. Тогда было бы неплохо выяснить, как включить jar-файлы зависимостей maven, такие как Gson или Otto. - person Sam; 31.03.2014
comment
Мне кажется, что это ломается, когда я добавляю ароматы, потому что он пытается создать несколько задач с одинаковыми именами без включения аромата. Я не парень Groovy и не могу понять, как добавить оттенок имени задачи. Буду признателен за любые подсказки, как это сделать. - person Kevin; 17.06.2014
comment
У меня было небольшое дополнение к решению Джейка, которое учитывает любые ресурсы Java - добавьте task.dependsOn variant.processJavaResources и task.from variant.processJavaResources.destinationDir (извините, не могу понять, как это правильно отформатировать) - person Piklor; 03.07.2014
comment
Может кто-нибудь указать, как я могу использовать proguard с этой конфигурацией? Кажется, что определение buildTypes с помощью proguard неприменимо. - person MikeL; 13.08.2014
comment
@Kevin, я заменил часть "jar${name.capitalize()}" на "jar${variant.name.capitalize()}", чтобы задача также учитывала имя аромата (variant.name состоит из имени buildType и имени productFlavor) - person dbm; 22.12.2014
comment
@SamDozor, пожалуйста, перейдите по ссылке для поддержки proguard Survivingwithandroid.com/2014/05/ - person Jani; 23.01.2015
comment
@Piklor, я пытался добавить ваши строки для включения ресурсов, но это не сработало. Не могли бы вы назвать весь код задачи, который вы использовали, пожалуйста - person keno; 25.03.2015
comment
@keno, к сожалению, я не могу найти нужный код. - person Piklor; 27.03.2015
comment
кажется, что это не собирается упаковывать ресурс .png в .jar, есть ли способ упаковать ресурс изображения в банку? - person 2cupsOfTech; 31.08.2015
comment
@CommonsWare есть какие-нибудь мысли об упаковке изображений с помощью gradle в jar? - person 2cupsOfTech; 31.08.2015
comment
@ 2cupsOfTech: Ну, вы не можете поместить ресурсы Android в JAR, только в AAR. Вы можете поиграть с классическими ресурсами Java в JAR, но я не пробовал, и обычно это не делается. - person CommonsWare; 31.08.2015
comment
@CommonsWare этот скрипт не создает запутанную банку, я полагаю, это возможно? - person 2cupsOfTech; 10.09.2015
comment
@ 2cupsOfTech: бей меня - person CommonsWare; 10.09.2015
comment
@ jake-wharton, как создать запутанную банку с помощью вашего скрипта? - person 2cupsOfTech; 10.09.2015
comment
@ 2cupsOfTech для создания обфусцированного jar-файла. Я использовал альтернативный метод копирования Jar-файла, который уже был сгенерирован сборкой библиотеки в / build / intermediateates / bundles / release (как упоминал Яни). Думаю, Яни должен здесь дать альтернативный ответ. Он работает как для обфусцированных, так и для не обфусцированных библиотек и мне кажется более простым. - person Olinasc; 03.11.2015
comment
@Jani, вы должны опубликовать здесь ответ своим альтернативным методом. Это поможет другим, поскольку также обрабатывает запутанные случаи. - person Olinasc; 03.11.2015
comment
@Olinasc Я закончил тем, что написал небольшой сценарий оболочки, чтобы преобразовать банку в обфусцированную банку с помощью proguard - person 2cupsOfTech; 03.11.2015
comment
@ 2cupsOfTech Я понимаю. Однако это кажется большим объемом работы, чем необходимо. Я отправлю здесь альтернативный ответ, если Яни не ответит. - person Olinasc; 03.11.2015
comment
@Olinasc - это однострочный скрипт, посмотрите на команду: 'java -jar -outjars -injars', мой скрипт не является общим, иначе я бы опубликовал, эта ссылка может быть полезна: proguard.sourceforge.net/manual/examples.html - person 2cupsOfTech; 03.11.2015
comment
@ 2cupsOfTech У меня больше нет доступа к файлу build.gradle, в котором я использовал этот альтернативный метод. Пожалуйста, опубликуйте ответ. Извините за неудобства. - person Jani; 04.11.2015

Другой способ сгенерировать jar из проекта библиотеки через gradle:

В вашей библиотеке build.gradle:

def jarName = 'someJarName.jar'

task clearJar(type: Delete) {
    delete "${project.buildDir}/libs/" + jarName
}

task makeJar(type: Copy) {
    from("${project.buildDir}/intermediates/bundles/release/")
    into("${project.buildDir}/libs/")
    include('classes.jar')
    rename('classes.jar', jarName)
}

makeJar.dependsOn(clearJar, build)

Мы просто копируем classes.jar, сгенерированный плагином Android Gradle. Обязательно загляните в каталог сборки для этого файла и посмотрите, соответствует ли его содержимое нужному вам.

Затем запустите задачу makeJar, и полученный jar будет в library / build / libs / ${jarName}.jar

У них будут файлы классов в соответствии с вашей конфигурацией для выпуска. Если вы запутаете его, тогда файлы в банке будут запутаны.

person Olinasc    schedule 13.11.2015

Просто потому, что предыдущие ответы не соответствовали моим потребностям, я делюсь своей сложной версией для создания jar-файла с классами проекта и зависимостями aar / jar.

// A tricky jar operation, we want to generate a jar files that contains only the required classes used.
// Dependencies are in jar and aar, so we need to open the aar to extract the classes and put all at the same level
// (aar is a zip that contains classes.jar, the latter is a zip that contains .class files)
task jar(type: Jar) {
    from {
        List<File> allFiles = new ArrayList<>();
        configurations.compile.collect {
            for (File f : zipTree(it).getFiles()) {
                if (f.getName().equals("classes.jar")) {
                    allFiles.addAll(zipTree(f).getAt("asFileTrees").get(0).getDir())
                }
            }
        }
        allFiles.add(new File('build/intermediates/classes/release'))
        allFiles // To return the result inside a lambda
    }
    archiveName( project.ext.appName + '.jar' )
}

Это НЕ управляет типами / вариантами сборки, но может быть адаптировано (это нормально для сборки с выпуском типа сборки без вкуса).

Если у вас когда-нибудь появится более умное или элегантное решение, поделитесь!

person Kikiwa    schedule 23.03.2016