Android Studio - задача сборки Gradle

В настоящее время я борюсь с процессом сборки в gradle. Моя цель - не иметь определенного класса Java в окончательном .apk для определенного вкуса. Логика выглядит следующим образом:

1.) перед компиляцией моего проекта удалите MyClass.java и скопируйте его во временную папку

2.) после сборки apk скопируйте обратно MyClass.java в исходную папку

3.) удалить временную папку

Это происходит только в том случае, если я создаю определенный вариант, поэтому это не происходит для всех вариантов сборки. Мой код отлично работает, когда я создаю только один вариант и один вариант сборки, например. assembleFlavorRelease, но если я не хочу, чтобы мой код работал для нескольких типов сборки; если я запущу assembleFlavor, он должен собрать flavorDebug так же, как и flavorRelease. Однако моя логика работает только в первый раз, а после этого она останавливается, поэтому флейвордебаг строится с MyClass, а этого быть не должно, в то время как флейворРелиз не включает MyClass в .apk, потому что мой код запускается в первый раз.

Вот как выглядит код:

task copyResource << {
    copy {
        from 'src/main/java/MyClass.java'
        into 'src/temp'
    }
}

task deleteResource << {
    delete {
        'src/main/java/MyClass.java'
    }
}

task deleteTemp << {
    delete {
        'src/temp'
    }
}

task copyBackToSource << {
    copy {
        from 'src/temp/MyClass.java'
        into 'src/main/java'
    }
    deleteTemp.execute()
}

android.applicationVariants.all { variant ->
    if (variant.name.contains('flavor')) {
        deleteResource.dependsOn copyResource
        variant.javaCompile.dependsOn deleteResource
        variant.assemble.doLast {
            copyBackToSource.execute()
        }
    }
}

Я думаю, что каталоги, которые я использую в своем коде, каким-то образом заблокированы при попытке выполнить весь процесс во второй раз?


person box    schedule 21.07.2015    source источник


Ответы (2)


Мне кажется, вы неправильно подходите к проблеме. Вместо того, чтобы думать

Поместите файл Java в src/main/java и удалите его из FlavorX.

Вместо этого вы должны подходить к нему как к

Добавьте дополнительный исходный каталог в исходные наборы для flavorY и FlavorZ.

Когда вы подходите к проблеме таким образом, становится намного легче

Если вам нужен файл только одного варианта, вы можете поместить файл в исходную папку для конкретного варианта, используя встроенные соглашения (например, src/flavorX/java)

Если вам нужен файл более чем в одном варианте, вы можете поместить MyClass.java в src/common/java и сделать что-то вроде

android {
   productFlavors {
       flavor1 {
       }
       flavor2 {
       }
       flavor3 {
       }
   }
}
sourceSets {
    flavor1.java = ['src/flavor1/java','src/common/java']
    flavor2.java = ['src/flavor2/java','src/common/java']
}
person lance-java    schedule 21.07.2015
comment
Спасибо за ответ, я знаю о таком решении. Проблема в том, что структура моего приложения сложна, и у меня есть 7 разных вариантов, а это означает, что мне придется несколько раз дублировать MyClass.java в src ароматов, которые его включают, плюс структура src аромата не видна в Android Studio под вид андроида насколько мне известно. Я хочу избежать этого решения, и я предпочитаю свое решение для своей структуры приложения. Есть ли другой способ исключить определенный класс? - person box; 22.07.2015
comment
что означает, что мне придется дублировать MyClass.java несколько раз, это неверно. Я дал два решения: одно, если вам нужен файл в одном варианте, другое, которое включает один исходный каталог двух или более вариантов без дублирования исходного файла. плюс структура src аромата не видна в Android Studio под видом Android, поскольку я знаю, что был бы удивлен, если бы это было так. - person lance-java; 22.07.2015
comment
О да, извините, вы правы, я мог бы поставить класс общим. Я пробовал это раньше, но, как я уже сказал, это не очень хорошо видно в структуре проекта и создает некоторые другие проблемы. Ниже я разместил правильное решение, которое чистое и прекрасно работает. - person box; 22.07.2015
comment
Я бы сказал, что ваше решение скорее грязное, чем чистое: P. Представьте, если MyClass.java требует дополнительной зависимости - person lance-java; 22.07.2015
comment
Если я использую ваш вариант, src, специфичный для вкуса, не отображается в AndroidStudio в представлении Android, что является лишь одной из проблем среди других. - person box; 22.07.2015
comment
См. здесь для активации вкус в андроид студии - person lance-java; 22.07.2015
comment
Ссылка выше показывает представление проекта, которое не является Android. В любом случае, если я использую src для ароматов, при его создании возникает ошибка из-за зависимости. - person box; 22.07.2015
comment
Недавно у меня возникли некоторые проблемы с тем, как я исключал отдельные файлы. Я отказался от этого метода и воспользовался вашей концепцией, которая решила мою проблему. - person box; 15.09.2015
comment
Здорово! Удалось ли вам сделать источник «видимым» в AndroidStudio? - person lance-java; 17.09.2015
comment
На самом деле я сделал да, хотя классы теперь видны, они не находятся в той же структуре пакета, но это не такая уж большая проблема. - person box; 17.09.2015

Итак, я получил правильное решение отсюда: https://discuss.gradle.org/t/android-gradle-assemble-tasks/10711

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

variant.javaCompile.exclude '**/SourceFileToExclude.java'
person box    schedule 22.07.2015
comment
Как я уже сказал, на мой взгляд, это неправильный способ решения проблемы. Исключения отдельных файлов неприятны. Аддитивные наборы исходных кодов гораздо проще поддерживать (подумайте о следующем бедолаге, который смотрит на код). - person lance-java; 22.07.2015
comment
В моем случае работает лучше. Я отметил ваш ответ как полезный, хотя не могу отметить его как ответ на свой вопрос. Я ценю вашу помощь. - person box; 22.07.2015