java - studio - ultimo gradle
Nuevo sistema de compilaciĆ³n de Android(gradle) y aspectj (5)
En Google IO, el nuevo sistema de compilación gradle se anuncia para reemplazar a ant. Mi proyecto está utilizando aspectj y me gustaría usarlo en mi proyecto. No pude averiguar algunas variables para que funcione. No encuentro android. * Salida classpath allí. ¿Alguien puede ayudar?
Aquí está mi build.gradle actual:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath ''com.android.tools.build:gradle:0.4''
}
}
apply plugin: ''android''
sourceCompatibility = 1.6
configurations {
ajc
}
dependencies {
compile fileTree(dir: ''libs'', includes: [''*.jar''])
ajc files(''build-tools/aspectjtools.jar'', ''libs/aspectjrt.jar'')
}
android {
compileSdkVersion 16
buildToolsVersion "17"
defaultConfig {
minSdkVersion 8
targetSdkVersion 16
}
sourceSets {
main {
manifest.srcFile ''AndroidManifest.xml''
java.srcDirs = [''src'']
resources.srcDirs = [''src'']
aidl.srcDirs = [''src'']
renderscript.srcDirs = [''src'']
res.srcDirs = [''res'']
assets.srcDirs = [''assets'']
}
instrumentTest.setRoot(''test'')
}
}
gradle.projectsEvaluated {
compileJava.doLast {
tasks.compileAspectJ.execute()
}
println ''lalalalala''
}
task compileAspectJ {
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties",
classpath: configurations.ajc.asPath)
ant.iajc(source: sourceCompatibility, target: sourceCompatibility,
destDir: "?????????????????????",
classpath: "????????????????????????????") {
sourceroots{
android.sourceSets.main.java.srcDirs.each {
pathelement(location: it.absolutePath)
}
}
}
}
Este es el antiguo código ant que funciona muy bien: http://code.google.com/p/anymemo/source/browse/custom_rules.xml
Editar:
Se actualizó build.gradle de acuerdo con la primera respuesta. Sin embargo, parece que iajc no reconoce todas las bibliotecas y se queja de las clases que no se encuentran
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath ''com.android.tools.build:gradle:0.5.+''
}
}
apply plugin: ''android''
sourceCompatibility = 1.6
targetCompatibility = 1.6
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "18.1.0"
defaultConfig {
minSdkVersion 9
targetSdkVersion 16
}
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'')
}
}
configurations {
ajc
aspects
ajInpath
}
ext.aspectjVersion = ''1.7.3''
dependencies {
compile fileTree(dir: ''libs'', include: ''*.jar'')
ajc "org.aspectj:aspectjtools:${aspectjVersion}"
compile "org.aspectj:aspectjrt:${aspectjVersion}"
compile ''com.android.support:appcompat-v7:18.0.0''
}
android.applicationVariants.all { variant ->
variant.javaCompile.doLast {
def androidSdk = android.adbExe.parent + "/../platforms/" + android.compileSdkVersion + "/android.jar"
println ''AAAAAAAAAAAAAAAAA: '' + androidSdk
def iajcClasspath = configurations.compile.asPath + ":" + androidSdk
configurations.compile.dependencies.each { dep ->
if(dep.hasProperty("dependencyProject")) {
iajcClasspath += ":" + dep.dependencyProject.buildDir + "/bundles/release/classes.jar"
}
}
println ''BBBBBBBBBBBBBB : '' + iajcClasspath
ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
ant.iajc (
source:sourceCompatibility,
target:targetCompatibility,
destDir:"${project.buildDir}/classes/${variant.dirName}",
maxmem:"512m",
fork:"true",
aspectPath:configurations.aspects.asPath,
inpath:configurations.ajInpath.asPath,
sourceRootCopyFilter:"**/.svn/*,**/*.java",
classpath:iajcClasspath
){
sourceroots{
android.sourceSets.main.java.srcDirs.each{
pathelement(location:it.absolutePath)
}
pathelement(location:"${project.buildDir}/source/r/${variant.dirName}")
}
}
}
}
Errores:
1 [error] The method onPrepareOptionsMenu(Menu) of type FingerPaint must override or impl[3780/18642]
rtype method
[ant:iajc] public boolean onPrepareOptionsMenu(Menu menu) {
[ant:iajc] ^^^^^^^^^^^^^^^^^^^^^^^^^^
[ant:iajc] /home/liberty/mp/android/AnyMemo/src/com/example/android/apis/graphics/FingerPaint.java:21
2 [error] The method onPrepareOptionsMenu(Menu) is undefined for the type GraphicsActivity
[ant:iajc] super.onPrepareOptionsMenu(menu);
[ant:iajc] ^^^^^^^^^^^
[ant:iajc] /home/liberty/mp/android/AnyMemo/src/com/example/android/apis/graphics/FingerPaint.java:21
7 [error] The method onOptionsItemSelected(MenuItem) of type FingerPaint must override or implement a
supertype method
[ant:iajc] public boolean onOptionsItemSelected(MenuItem item) {
[ant:iajc] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ant:iajc] /home/liberty/mp/android/AnyMemo/src/com/example/android/apis/graphics/FingerPaint.java:22
8 [error] The constructor ColorPickerDialog(FingerPaint, FingerPaint, int) is undefined
[ant:iajc] new ColorPickerDialog(this, this, mPaint.getColor()).show();
[ant:iajc] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ant:iajc] /home/liberty/mp/android/AnyMemo/src/com/example/android/apis/graphics/FingerPaint.java:25
4 [error] The method onOptionsItemSelected(MenuItem) is undefined for the type GraphicsActivity
[ant:iajc] return super.onOptionsItemSelected(item);
[ant:iajc] ^^^^^^^^^^^^
[ant:iajc] /home/liberty/mp/android/AnyMemo/src/com/example/android/apis/graphics/FingerPaint.java:25
8 [error] The method getDefaultSharedPreferences(Context) in the type PreferenceManager is not applic
able for the arguments (FingerPaint)
[ant:iajc] SharedPreferences shre = PreferenceManager.getDefaultSharedPreferences(this);
[ant:iajc]
EDITAR: Este es el archivo final build.gradle que funciona para mi proyecto: https://code.google.com/p/anymemo/source/browse/build.gradle?spec=svnf85aaa4b2d78c62876d0e1f6c3e28252bf03f820&r=f85aaa4b2d78c62876d0e1f6c3e28252bf03f820 la foto de la naturaleza de la naturaleza de la naturaleza.
Aunque las secuencias de comandos de respuestas anteriores funcionan para la mayoría de las situaciones, no cubren algunos de los problemas de usar Android con AspectJ y Gradle.
Mi prueba fue crear un proyecto de biblioteca que debería ser utilizado por cualquier persona a través de mavenCentral o por mí como un proyecto de biblioteca de referencia y un proyecto de aplicación de prueba. El proyecto de la biblioteca es el que tiene todos los aspectos y la prueba de la aplicación estaba tratando de usar esos aspectos. Dando esto como contexto, la estructura del proyecto resultante fue:
HEAD-Gradle
---LibraryProject
-------SomeAspects
---TestApplication
-------Uses-SomeAspects
Las soluciones que encontré que lo hacen funcionar son:
1- Para proyectos bibliotecarios debes usar
libraryVariants.all { variant ->
en lugar de
android.applicationVariants.all { variant ->
2- El directorio de compilación cambió por 19. + las herramientas de compilación de Android, por lo que se sugiere en un comentario (gracias a "WithoutClass"), debe usar el directorio exploded-aar en lugar de exploded-bundles en la variable de árbol definición. Desde:
def tree = fileTree(dir: "${project.buildDir}/exploded-bundles", include: ''**/classes.jar'')
A:
def tree = fileTree(dir: "${project.buildDir}/exploded-aar", include: ''**/classes.jar'')
3- El último problema que enfrenté al realizar la integración fue que si tiene un proyecto de biblioteca, los aspectos definidos en él no se encontraron en el proyecto secundario. Para resolver esto, debe agregar el classes.jar de su biblioteca personalizada a la configuración del compilador de aspectJ. Puedes lograr esto agregando a las dependencias:
aspects project(":YourLibraryProject")
y también es necesario realizar algunos cambios en el script que se proporciona en la final de esta publicación.
En este momento, el mejor script que puedo imaginar que da soporte completo para aspectj al usar incluso proyectos de biblioteca es:
Para dependencias:
configurations {
ajc
aspects
ajInpath
}
//Version of aspectj
def aspectjVersion = ''1.8.+''
// The dependencies for this project
dependencies {
compile fileTree(dir: ''libs'', include: [''*.jar''])
//Your dependencies to a custom library project
compile project(":YourLibraryProject")
aspects project(":YourLibraryProject")
//Aspectj dependencies
ajc "org.aspectj:aspectjtools:${aspectjVersion}"
compile "org.aspectj:aspectjrt:${aspectjVersion}"
}
El compilador ejecutando script.
android.applicationVariants.all { variant ->
variant.javaCompile.doLast {
// Find the android.jar and add to iajc classpath
def androidSdk = android.adbExe.parent + "/../platforms/" + android.compileSdkVersion + "/android.jar"
def iajcClasspath = androidSdk + ":" + configurations.compile.asPath
//This line and the fordward assignations allow the aspects support in the child project from the library project
def customAspectsPath = configurations.aspects.asPath
configurations.compile.dependencies.each { dep ->
if(dep.hasProperty("dependencyProject")) {
iajcClasspath += ":" + dep.dependencyProject.buildDir + "/bundles/${variant.buildType.name}/classes.jar"
customAspectsPath += ":" + dep.dependencyProject.buildDir + "/bundles/${variant.buildType.name}/classes.jar"
}
}
// handle aar dependencies pulled in by gradle (Android support library and etc)
def tree = fileTree(dir: "${project.buildDir}/exploded-aar", include: ''**/classes.jar'')
tree.each { jarFile ->
iajcClasspath += ":" + jarFile
}
ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
ant.iajc (
source:sourceCompatibility,
target:targetCompatibility,
destDir:"${project.buildDir}/classes/${variant.dirName}",
maxmem:"512m",
fork:"true",
aspectPath:customAspectsPath,
inpath:configurations.ajInpath.asPath,
sourceRootCopyFilter:"**/.svn/*,**/*.java",
classpath:iajcClasspath
){
sourceroots{
android.sourceSets.main.java.srcDirs.each{
pathelement(location:it.absolutePath)
}
pathelement(location:"${project.buildDir}/source/r/${variant.dirName}")
}
}
}
}
Recuerde que si desea ejecutar AspectJ en un proyecto de biblioteca-hijo, también debe tener este script en el build.gradle de la biblioteca.
Descubrí que el AAR no se puede usar como una biblioteca de archivos en mi código. Si estas usando dependencias como esta
compile ''com.android.support:appcompat-v7:18.0.0''
Necesitas encontrar el archivo jar y agregarlo a la ruta de clases. El siguiente código lo hará.
tree = fileTree(dir: "${project.buildDir}/exploded-bundles", include: ''**/classes.jar'')
tree.each { jarFile ->
iajcClasspath += ":" + jarFile
}
Así que toda la sección sería:
variant.javaCompile.doLast {
// Find the android.jar and add to iajc classpath
def androidSdk = android.adbExe.parent + "/../platforms/" + android.compileSdkVersion + "/android.jar"
println ''Android SDK android.jar path: '' + androidSdk
def iajcClasspath = androidSdk + ":" + configurations.compile.asPath
configurations.compile.dependencies.each { dep ->
if(dep.hasProperty("dependencyProject")) {
iajcClasspath += ":" + dep.dependencyProject.buildDir + "/bundles/release/classes.jar"
}
}
// handle aar dependencies pulled in by gradle (Android support library and etc)
tree = fileTree(dir: "${project.buildDir}/exploded-bundles", include: ''**/classes.jar'')
tree.each { jarFile ->
iajcClasspath += ":" + jarFile
}
println ''Classpath for iajc: '' + iajcClasspath
ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
Para ver el ejemplo completo, consulte el proyecto build.gradle para el proyecto AnyMemo aquí: https://code.google.com/p/anymemo/source/browse/build.gradle?spec=svnf85aaa4b2d78c62876d0e1f6c3e28252bf03f820&r=f85aaa4b2d78c62876d0e1f6c3e28252bf03f820 las costillas de las partes de la actividad de las partes de la naturaleza de las actividades de la naturaleza.
En el caso de usar Android Studio 0.8 o superior, parece que usar gradle 0.12. + Es necesario.
En gradle 0.12. +, Los aar explotados se extraen en la carpeta de compilación, no en la carpeta explotada.
Por lo tanto, para manejar las dependencias aar, debe usar este código:
tree = fileTree(dir: "${project.buildDir}", include: ''**/classes.jar'')
tree.each { jarFile ->
iajcClasspath += ":" + jarFile
}
Otra forma más fácil de configurar las cosas es utilizando el complemento de android aspectj que se mantiene mejor. https://github.com/uPhyca/gradle-android-aspectj-plugin
También quería usar aspectj con gradle y Android Studio, y finalmente lo puse en funcionamiento, pero todavía tengo algunas rutas escritas a mano que me gustaría reemplazar con más opciones genéricas de gradle.
Edición: reemplacé todas las rutas absolutas codificadas con alternativas basadas en gradle, por lo que esta solución ya no depende de una plataforma o nombre de usuario determinado. Sin embargo, todavía utiliza rutas relativas que podrían cambiar de un IDE a otro o en versiones posteriores de Android Studio. Además, no estoy realmente satisfecho con la forma en que encuentro android.jar.
Primero cargue aspectj:
configurations {
ajc
aspects
ajInpath
}
ext.aspectjVersion = ''1.7.3''
dependencies {
compile project(":LibTest")
ajc "org.aspectj:aspectjtools:${aspectjVersion}"
compile "org.aspectj:aspectjrt:${aspectjVersion}"
compile ''com.android.support:appcompat-v7:18.0.0''
}
Y luego agrego una tarea que se ejecutará después de la tarea JavaCompile de la variante actual:
android.applicationVariants.all { variant ->
variant.javaCompile.doLast {
def androidSdk = android.adbExe.parent + "/../platforms/" + android.compileSdkVersion + "/android.jar"
def iajcClasspath = configurations.compile.asPath + ";" + androidSdk
configurations.compile.dependencies.each { dep ->
if(dep.hasProperty("dependencyProject")) {
iajcClasspath += ":" + dep.dependencyProject.buildDir + "/bundles/release/classes.jar"
}
}
ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
ant.iajc (
source:sourceCompatibility,
target:targetCompatibility,
destDir:"${project.buildDir}/classes/${variant.dirName}",
maxmem:"512m",
fork:"true",
aspectPath:configurations.aspects.asPath,
inpath:configurations.ajInpath.asPath,
sourceRootCopyFilter:"**/.svn/*,**/*.java",
classpath:iajcClasspath
){
sourceroots{
android.sourceSets.main.java.srcDirs.each{
pathelement(location:it.absolutePath)
}
pathelement(location:"${project.buildDir}/source/r/${variant.dirName}")
}
}
}
}
Siempre que use ${variant.dirName}
, será reemplazado por "debug" o "release" de acuerdo con la configuración de compilación actual.
Es necesario agregar android.jar a la ruta de clase para compilar clases específicas de Android, y la línea de pathelement(location:"${project.buildDir}/source/r/${variant.dirName}")
requiere usar clases desde el auto -generado archivo rjava.
Edición: las iteraciones sobre las dependencias del proyecto para construir iajcClasspath le permiten usar clases de sus proyectos de bibliotecas. configurations.compile.asPath
ya contiene una referencia a su apklib (archivo aar), que en realidad es un zip que contiene tanto el jar como los recursos de la biblioteca. Iajc no reconoce estos archivos como ellos, pero hay un directorio de paquete que contiene classes.jar para su biblioteca en el directorio de compilación. Utilizo una ruta relativa con "versión" codificada, ya que la biblioteca tiene una variante diferente a la del proyecto principal en mi situación, por lo que no puedo usar ${variant.dirName}
aquí.
Aquí está el archivo build.gradle completo:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath ''com.android.tools.build:gradle:0.5.+''
}
}
apply plugin: ''android''
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "18.1.0"
defaultConfig {
minSdkVersion 7
targetSdkVersion 18
}
}
configurations {
ajc
aspects
ajInpath
}
ext.aspectjVersion = ''1.7.3''
dependencies {
compile project(":LibTest")
ajc "org.aspectj:aspectjtools:${aspectjVersion}"
compile "org.aspectj:aspectjrt:${aspectjVersion}"
compile ''com.android.support:appcompat-v7:18.0.0''
}
android.applicationVariants.all { variant ->
variant.javaCompile.doLast {
def androidSdk = android.adbExe.parent + "/../platforms/" + android.compileSdkVersion + "/android.jar"
def iajcClasspath = configurations.compile.asPath + ";" + androidSdk
configurations.compile.dependencies.each { dep ->
if(dep.hasProperty("dependencyProject")) {
iajcClasspath += ":" + dep.dependencyProject.buildDir + "/bundles/release/classes.jar"
}
}
ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
ant.iajc (
source:sourceCompatibility,
target:targetCompatibility,
destDir:"${project.buildDir}/classes/${variant.dirName}",
maxmem:"512m",
fork:"true",
aspectPath:configurations.aspects.asPath,
inpath:configurations.ajInpath.asPath,
sourceRootCopyFilter:"**/.svn/*,**/*.java",
classpath:iajcClasspath
){
sourceroots{
android.sourceSets.main.java.srcDirs.each{
pathelement(location:it.absolutePath)
}
pathelement(location:"${project.buildDir}/source/r/${variant.dirName}")
}
}
}
}