Подтвердить что ты не робот

Доступ к значению sdk.dir в build.gradle после оценки проекта

У меня есть пользовательская задача в моем файле build.gradle, который преобразует байт-коды в файлы классов, прежде чем получить dex'd, который выглядит так:

task droidcook(type: JavaExec) {
    main 'org.tsg.android.asm.Main'
}

afterEvaluate { project ->
    android.applicationVariants.each { variant ->
        variant.javaCompile.doLast {
            project.tasks.droidcook.configure {
                classpath variant.javaCompile.classpath
                classpath "build/classes/" + variant.dirName
                classpath sdk.dir + "/platforms/android-19/android.jar"
                classpath "compile-libs/droidcook.jar"
                args "build/classes/" + variant.dirName
                args "com.example"
                // args "-debug"
                // args "-asmifier"
            }
            project.tasks.droidcook.execute()
        }
    }
}

Проблема с вышесказанным - это строка classpath sdk.dir + ..., где sdk.dir не оценивается соответствующим образом. Чтобы получить эту работу, мне в настоящее время нужно жестко закодировать путь к android.jar.

Бонусные баллы, если вы можете ответить с соответствующим значением, чтобы заменить android-19 на доступ к платформе android.jar на основе конфигурации проекта.: D

4b9b3361

Ответ 1

Я не вижу опубликованного API, чтобы выставлять файл sdk.dir в ваш файл сборки, поэтому я просто скрепил код https://android.googlesource.com/platform/tools/build/+/d69964104aed4cfae5052028b5c5e57580441ae8/gradle/src/main/groovy/com/android/build/gradle/internal/Sdk.groovy, чтобы прочитать его вручную. Что касается замены android-19, если я читаю android.compileSdkVersion, я получаю эту точную строку. Я не уверен, что это тоже опубликованный API, поэтому он может быть изменен и поврежден в будущих версиях плагина Android Gradle.

Сказав это, это работает для меня:

afterEvaluate {
    def rootDir = project.rootDir
    def localProperties = new File(rootDir, "local.properties")
    if (localProperties.exists()) {
        Properties properties = new Properties()
        localProperties.withInputStream { instr ->
            properties.load(instr)
        }
        def sdkDir = properties.getProperty('sdk.dir')
        def androidJarPath = sdkDir + "/platforms/" + android.compileSdkVersion + "/android.jar"
        print androidJarPath + "\n"
    }
}

Если нет local.properties, этот код будет терпеть неудачу. Если вам это интересно, вы можете скопировать больше кода из Sdk.groovy, чтобы подражать его поведению, пытаясь найти разумное значение по умолчанию.

Ответ 2

Там гораздо более простой способ, хотя он не документирован, поэтому он, вероятно, официально не поддерживается.

println "${android.getSdkDirectory().getAbsolutePath()}"

Как ни странно, этот метод доступен только для некоторых версий плагина gradle. Он не доступен в фиксации, связанной выше Скоттом. Если вышеуказанный код не работает, попробуйте следующее:

println "${android.plugin.getSdkFolder().getAbsolutePath()}"

Для полноты здесь также можно получить переменную ndk.dir:

println "${android.plugin.getNdkFolder().getAbsolutePath()}"

Ответ 3

Как и для андроида gradle плагин v2.1.2, это то, что я использую в своем gradle script:

android.ndkDirectory.path
android.sdkDirectory.path

Например, для явного запуска ndk-build:

task ndkBuild(type: Exec) {
    commandLine android.ndkDirectory.path+'/ndk-build', '-C', file('src/main').absolutePath
}

Ответ 4

Использование:

String androidJar = android.getBootClasspath()[0]

Предполагая, что вы используете SDK 21, это установит '< path-to-SDK > /platforms/android-21/android.jar' в переменную androidJar (выбор версии SDK выполняется автоматически).

Следующим шагом, очевидно, будет замена "classpath sdk.dir..." и т.д. с помощью

classpath androidJar