android - studio - Gradle: pros/contra que agregan dependencias
flavordimensions android (9)
La preocupación principalmente sobre el tamaño de tu aplicación de Android. Muchos de los métodos o clases pueden aumentar el límite de 64k en el archivo dex y, en su mayoría, requieren la habilitación de modos múltiples o jumbo. Eso puede crearte algún problema de compatibilidad si tienes clientes muy desactualizados.
En algún momento es posible que desee solucionarlo extrayendo solo las clases que necesitaba, pero no es un trabajo fácil en algún momento.
Si tiene proguard habilitado, las clases que no se utilizan pueden eliminarse sistemáticamente.
¿Cuáles son algunas dependencias que agregan pros / contras en build.gradle
, en lugar de agregarlas como bibliotecas dependientes?
dependencies {
compile project('':library'')
...
compile ''com.stackoverflow.android:some-great-library:1.0''
...
}
Mientras trabajo en proyectos de Android, con frecuencia he encontrado grandes bibliotecas con la solución exacta que he estado buscando. Sin embargo, como lo que necesito es solo una fracción de lo que esas bibliotecas en particular tienen para ofrecer, me preocupa si agregarlas como Gradle dependencies
es una exageración .
Por el comentario de Per @ CommonsWare, tengo preguntas más específicas.
Tiene agregar dependencias:
ralentizar el tiempo de compilación a un ritmo notable
aumentar el tamaño de release-apk y debug-apk, tanto como el tamaño de la dependencia agregada?
Copiar el código de una biblioteca de terceros a su proyecto ocasiona algunos problemas al respaldar ese proyecto. ¿Qué sucede si necesita usar esa biblioteca de la versión más nueva? Si lo agrega como dependencia, todo lo que necesitará es cambiar el número de versión en la configuración del sistema de compilación.
Creo que esta pregunta no depende mucho de Gradle, sino que de manera más general, del uso de "herramientas de administración de dependencias".
Seguramente hay situaciones en las que solo necesitamos un subconjunto de una biblioteca. En estas situaciones, tener que importar toda la dependencia puede no ser la mejor solución.
¿Cuánto es "excesivo"? Obviamente, depende del tamaño de tu proyecto. Depende de usted evaluar cuánto "exagerado" puede ser una dependencia: por ejemplo, si solo necesita una función simple y está importando una biblioteca de 3MB, probablemente sí, ¡es un poco exagerado!
Además, debe tener en cuenta que, en general, las bibliotecas "grandes" se dividen en módulos y, por lo tanto, solo puede importar el módulo que necesita. En el caso de Android, como dijo @phdfond, puede usar ProGuard para eliminar las clases no utilizadas en tiempo de compilación, o puede excluirlas manualmente con Gradle:
//...
sourceSets {
main {
java {
exclude ''**/IDontWantThisClass.java''
}
}
Pero en mi humilde opinión, esta situación no es muy común y puede tener muchas ventajas al usar Gradle u otra "herramienta de administración de dependencias" (tenga en cuenta que en Gradle, Maven, ecc ... la gestión de dependencias es solo una de sus funcionalidades).
Por ejemplo, si está usando Gradle de un vistazo, conoce sus dependencias y puede agregarlas / eliminarlas fácilmente o simplemente cambiar un número para actualizar su versión. ¿Alguna vez pensaste que tu proyecto puede depender de las bibliotecas B y C, y tanto B como C pueden depender de dos versiones diferentes de una lib D? Well Gradle también puede ayudarte en situaciones como esta. No puedo continuar aquí porque estaría fuera del tema, pero puedes encontrar mucha información sobre estas herramientas.
Finalmente, creo que el "CONS" más importante de "herramientas de gestión de dependencias" es el tiempo inicial de aprendizaje y configuración. Si nunca usaste una herramienta como Gradle, seguramente los primeros tiempos tomarán más tiempo que arrastrar y soltar un frasco, por lo que te recomiendo usar Gradle en tus proyectos, a menos que sea un "proyecto de juguete".
Si se debe agregar una biblioteca de terceros como dependencia
Declara una dependencia a una biblioteca de terceros cuando su programa utiliza algún código en esta biblioteca en tiempo de compilación o en tiempo de ejecución. Eso significa que el código de terceros debe ser accesible cuando se ejecuta su programa, por lo que está empaquetado con su programa. Por lo tanto, el tamaño de la aplicación aumenta y esto no se desea, porque a muchos usuarios no les gustan las aplicaciones grandes. También esto es ridículo, cuando tu programa es pequeño y la biblioteca de terceros es enorme.
Si se debe agregar una biblioteca de terceros como módulo
Nunca he hecho eso, pero si lo entendí bien, es lo mismo que copiar la biblioteca dentro de tu proyecto, para que puedas modificarlo. Si utiliza versiones, no habrá diferencia de tiempo de compilación con la compilación de dependencia remota. Todo es igual que en el párrafo anterior, pero además puede modificar el código (si la licencia de una biblioteca de terceros lo permite).
Si agregar extraer solo el código que necesita
Esta es la mejor solución para usar, si necesita solo unos pocos métodos de una biblioteca y no es difícil extraerlos (una vez más, suponiendo que la licencia lo permita). Por otro lado, si usa alguna funcionalidad sólida de terceros y desea extraerla y modificarla en su proyecto, puede enfrentar problemas de mantenimiento en el futuro (si decide migrar a una nueva versión).
¿Agregar dependencias: ralentiza el tiempo de compilación a un ritmo notable?
Con el ajuste correcto de Gradle (trabajando como daemon en segundo plano, usando el procesamiento paralelo) no verá ningún cambio dramático en un proyecto típico.
¿Agrega dependencias: aumenta el tamaño de release-apk y debug-apk, tanto como el tamaño de la dependencia agregada?
El contenedor de dependencia se envía a dex para la conversión de código de bytes y su código de proyecto. Esta no es una conversión 1: 1 en términos de tamaño, por lo que la respuesta es no. También ProGuard tiene algunos trucos para minimizar el tamaño de las jarras y Maven tiene un complemento para empaquetar todas las jarras dependientes en una, por lo que todas podrían ofuscarse.
Yo diría que son fundamentalmente cosas diferentes.
1. Subproyecto de Gradle
dependencies {
compile project('':foobarlib'')
}
En este primer caso, depende de un subproyecto de Android, parte del proyecto Gradle en el que está trabajando. También puede llamar a este tipo de dependencia un module
, como Intellij
hace Intellij
.
Si desea realizar un cambio, puede hacerlo y todo lo que necesita para que ese cambio sea visible es una compilación de gradle del proyecto de root gradle.
2. Proyecto de biblioteca Android
dependencies {
compile ''com.example:foobarlib:2.1.0''
}
En este segundo caso, lo que depende de usted es un artefact
(es decir, un archivo en formato JAR
o AAR
), no un proyecto. Esto es esencialmente una caja negra para su proyecto gradle. Todo lo que Gradle sabe es que contiene clases compiladas (y recursos en caso de un AAR) que su proyecto necesita.
Si desea realizar un cambio en la biblioteca, primero debe ubicar su proyecto correspondiente para editar sus fuentes, compilar el proyecto y publicar el nuevo artefacto en un maven repository
local o remoto de maven repository
. Finalmente, para que su proyecto vea los cambios realizados en este otro proyecto, deberá actualizar el número de versión declarado en la dependencia para que Gradle sepa que tendrá que traer el artefacto recién publicado.
¿Cuál es mejor?
Depende, por supuesto. Solo piense si la biblioteca tiene sentido o no, o si es solo un módulo de su aplicación. Como viste, el segundo enfoque agrega demasiada sobrecarga si solo estás trabajando en un módulo de tu aplicación y tampoco tiene sentido versionar y distribuir esos cambios sin el resto de la aplicación.
¿Qué son los pros / contra que agregan dependencias de un subproyecto en un proyecto de compilación de Gradle?
dependencies {
compile project('':library'')
}
Pros
- Cambio de código en: el subproyecto de la biblioteca es posible
Contras
- Administre usted mismo la Versión del: Subproyecto de biblioteca
¿Qué son los pros / contra que agregan dependencias de una biblioteca dependiente versionada a en Gradle Build Project?
dependencies {
compile ''com..android:some-great-library:1.0''
}
Pros
- Dependencia directa clara, incluida la versión de la biblioteca utilizada
- Dependencias indirectas claras administradas (es decir, la Biblioteca utilizada utiliza otra Biblioteca - Archivos POM)
- Otra persona / grupo gestiona la funcionalidad de la biblioteca: puede centrarse en su propio código.
Contras
- Ninguna
¿Agregar dependencias como: biblioteca Subproyecto ralentiza el tiempo de compilación a un ritmo notable?
- Sí, también deben compilarse, porque están en el código fuente de su subproyecto
- Gradle optimze builtime con definición de entrada / salida de una tarea. Consulte los marcadores ACTUALIZADOS durante la construcción.
¿La adición de dependencias como biblioteca dependiente de versiones disminuye el tiempo de compilación a un ritmo notable?
- No, porque las Bibliotecas (.jar) ya están compiladas.
¿La adición de dependencias aumenta el tamaño de release-apk y debug-apk, tanto como el tamaño de la dependencia agregada?
- El tamaño apk aumenta el tamaño binario (.jar = Archivos .class comprimidos) de la dependencia añadida.
- (Si tiene Proguard habilitado, las clases que no se están utilizando se pueden eliminar de forma sistemática, desde el usuario phdfong)
La dependencia de Gradle es una exageración
Bueno, es así si está utilizando una biblioteca estable o si está satisfecho con las características actuales de la biblioteca. También cuando la biblioteca tiene dependencias para portar hacia atrás o tiene un conjunto de características o clases que simplemente no necesita.
La solución será tomar lo que necesite de la biblioteca (solo cuando esté seguro de que será suficiente).
Y no es
Si desea actualizaciones automáticas y correcciones a su biblioteca, facilidad de integración. Muchas de las bibliotecas se crean y mantienen todos los días, por lo que puede ser que el tamaño del archivo APK no nos importe tanto, como la biblioteca actualiza, por lo que las importaciones de gradle son buenas allí.
Preocupaciones sobre el tamaño del APK
Una dependencia gradle puede tener muchas cosas no relacionadas, la compatibilidad con versiones anteriores que no requiere su aplicación, que al final aumenta el tamaño de la aplicación, también provocará una compilación lenta.
Entonces, si la biblioteca tiene una sola clase o menos clases, puede agregarla directamente a su aplicación en algún paquete. Un buen ejemplo será la aplicación Google IO, donde algunas bibliotecas están en un paquete diferente.
También puede controlar lo que va a depurar o lanzar apk, para depurar dependencias usar debugCompile
, para las dependencias de prueba use testCompile
Agregar la biblioteca como dependencia del módulo
Agregar como módulo de biblioteca acelerará el proceso de compilación según el tiempo de descarga requerido para recuperar la dependencia, lo cual se puede lograr fácilmente mediante Habilitar la sincronización sin conexión para Gradle en el estudio de Android.
También los módulos de biblioteca son el camino, si ha desarrollado una biblioteca privada y la usa en sus propios proyectos, si ese no es el caso, tendrá la biblioteca publicada y mantenida en Maven Central y será más fácil de integrar a su propio conjunto de proyectos a través de Gradle.
1. slow down compilation time at a noticeable rate?
Respuesta corta: sí.
Respuesta larga: actualmente estamos usando Gradle
en nuestro proyecto y existe una diferencia CONSIDERABLE en el tiempo de compilación que he experimentado. Esto es especialmente cierto si tiene un proyecto que tiene dependencias de múltiples módulos. Además, sin mencionar el hecho de que si sigues sumando muchas dependencias solo para usar un montón de clases de cada una de ellas, eventualmente te toparás con las muy famosas:
Too many references: 66539 error; max is 65536.
He experimentado esto un montón de veces ( gradle
y maven
) al usar bibliotecas que requieren gradle
recursos (por ejemplo, play-services
de play-services
).
2. `increase the size of release-apk and debug-apk, as much as the size of the added dependency?`
Definitivamente lo hace. No tanto para el release-apk ya que puedes optimizar proguard para cualquier extensión que desees. En el caso de debug-apk, he visto variaciones de tamaño de hasta 5-6 MB.
Solo mis 2 centavos. Espero que esto ayude.
Las dependencias de Gradle se agrupan en configuraciones como configuraciones de dependencia. La dependencia externa es una dependencia de algunos archivos creados fuera de la compilación actual, y se almacena en un repositorio de algún tipo, como Maven central, o un repositorio corporativo de Maven o Ivy, o un directorio en el sistema de archivos local.
Tipos de dependencia:
Dependencia de módulo externo:
Una dependencia de un módulo externo en algún repositorio.
Dependencia del proyecto:
Una dependencia de otro proyecto en la misma construcción.
Dependencia de archivo:
Una dependencia de un conjunto de archivos en el sistema de archivos local.
Dependencia del módulo cliente:
Una dependencia de un módulo externo, donde los artefactos se encuentran en algún repositorio pero los metadatos del módulo son especificados por la construcción local. Utiliza este tipo de dependencia cuando desea anular los metadatos del módulo.
Dependencia de Gradle API:
Una dependencia de la API de la versión actual de Gradle. Utiliza este tipo de dependencia cuando desarrolla plugins y tipos de tareas personalizados de Gradle.
Dependencia local de Groovy:
Una dependencia de la versión de Groovy utilizada por la versión actual de Gradle. Utiliza este tipo de dependencia cuando desarrolla plugins y tipos de tareas personalizados de Gradle.
Pros agregando dependencias:
En Gradle, simplemente declara los "nombres" de sus dependencias, y otras capas determinan de dónde obtener esas dependencias.
Cambio de código posible en SubProyecto.
Dependencia directa clara, incluida la versión de la biblioteca utilizada
Dependencias indirectas claras administradas (es decir, la Biblioteca utilizada utiliza otra Biblioteca - Archivos POM) {del usuario Robert Halter).disponibilidad en línea dependiente
La biblioteca require sdk ya está sincronizada con el proyecto para las compilaciones.
Contras:
Como tal, no tiene inconvenientes, pero en la etapa inicial al agregar dependencias tenemos que sincronizarlo, lo que lleva un poco más de tiempo que simplemente arrastrar y soltar el archivo jar.
¿Desacelera el tiempo de compilación a un ritmo notable?
No, porque las bibliotecas se compilan solo en el momento de la sincronización.
¿Aumenta el tamaño de release-apk y debug-apk, tanto como el tamaño de la dependencia agregada?
No, pero prácticamente sí porque solo toma el tamaño del archivo de compilación (tamaño binario) que apenas aumenta el tamaño en bytes o kb, que es difícil de rastrear.
Entonces, finalmente, agregarlos como dependencias de Gradle es una exageración cuando solo necesitamos usar una fracción de una biblioteca en particular.
Definitivamente, puede haber una situación como en su caso para usar solo un subconjunto de una biblioteca. Así que, en este caso, ProGuard optimiza el análisis de rendimiento en el nivel de bytecode, dentro y entre métodos para ayudar a que su aplicación sea más pequeña y funcione más rápido sin una sobrecarga .