Modo API explícito para Kotlin / Android | de Chao Zhang | Noviembre de 2020

Kotlin 1.4 introdujo una nueva característica interesante llamada modo API explícito. En este nuevo modo, las bibliotecas deben proporcionar modificadores de visibilidad explícitos y tipos de retorno explícitos. Por lo tanto, los autores de bibliotecas pueden estar libres de arrepentimientos futuros en caso de que expongan accidentalmente las API a sus empleados.

Al aplicar el modo API explícito en una base de código real, me resulta extremadamente útil identificar las API expuestas no intencionadas en la biblioteca. Mientras tanto, casi como se esperaba para cada nueva característica, descubrí algunos problemas junto con la adopción en nuestra base de código de Android.

Nota la La versión de Kotlin utilizada en esta historia es 1.4.10

De acuerdo a documentación, con el modo explícito habilitado, el compilador tendría los requisitos adicionales para compilar el código:

Se requieren modificadores de visibilidad: aunque teníamos la intención de dejar el modificador de visibilidad fuera para que se hiciera público, todavía necesitamos agregar público para no exponer involuntariamente la API.

Se requieren especificaciones de tipo explícitas para propiedades y funciones. Esto puede mejorar la disponibilidad y mantener la compatibilidad con versiones anteriores para que el tipo no se pueda cambiar implícitamente.

Además del modificador de visibilidad y los tipos de retorno, MANTENER También mencionó que la propagación explícita de la suscripción y la anotación KDoc se verifica en las API públicas. Sin embargo, estos son NO implementado desde Kotlin 1.4.10.

los gradle cambio del guion habilitarlo es simple. Sin embargo, dado que la base de código en la que estoy trabajando son las bibliotecas de Android, debemos modificarla para que funcione con el complemento de Android Gradle:

android.kotlinOptions.freeCompilerArgs = [“-Xexplicit-api=strict”]

Corriendo./gradlew build es casi seguro que fallará si aplicamos el modo explícito por primera vez. Los mensajes de error son simples:

e: AppLaunchMonitor.kt: (72, 5): Visibility must be specified in explicit API mode
e: AppLaunchMonitor.kt: (72, 16): Return type must be specified in explicit API mode
e: AppLaunchMonitor.kt: (530, 1): Visibility must be specified in explicit API mode

Aquí se ejemplifican dos ejemplos y ambos son buenas capturas:

En la línea 72, tenemos una propiedad booleana para hacer una verificación de la versión del SDK. Los extrañamos a los dos public como modificador de visibilidad e Boolean como tipo de retorno. ¡Esta es una buena captura y deberíamos hacerlas explícitas!

En la línea 530, exponemos involuntariamente una API pública para la constante. Si los clientes no ignoran el archivo VisibleForTesting anotación, debería estar bien. Como no podemos garantizarlo, ¡solucionémoslo!

Sería relajante si lo que necesitamos es el flujo de trabajo anterior. Pero como siempre, encontramos nuevos problemas y nuevas soluciones.

Inspección IDE
los public el modificador de visibilidad se disuelve en Android Studio, porque nos dice que son redundantes. Para embellecer el aspecto de nuestro código, podemos desactivar la inspección predeterminada por completoKotlin | Redundant constructs | Redundant visibility modifier o reducir su gravedad lo suficiente para que ya no sea diferente de otros códigos en el color.

Control del modificador de visibilidad redundante

Código de prueba

Con android.kotlinOptions.freeCompilerArgs = [“-Xexplicit-api=strict”] , el argumento del compilador se agrega tanto al conjunto de fuentes principal 👍 como a los conjuntos de fuentes de prueba. Esto es extremadamente inconveniente porque el código de prueba no está ensamblado en el AAR, por lo que no se expone como una API pública. Necesitamos el modo API OFF explícito para compilar, de lo contrario, ¡tendremos que refactorizar todo nuestro código de prueba!

Para habilitar el modo API explícito de forma explícita para el código principal, escribí un complemento de Gradle independiente como el siguiente, de modo que se excluye toda la compilación del código de prueba:

Reglas de Detekt en conflicto

Desde que tenemos Detekt configurada como nuestra herramienta de control de estilo, hay dos reglas para llamar aquí:

RedundantVisibilityModifierRule: Esta regla es en realidad contraria al modo API explícito. El consejo sería deshabilitar esta regla en la configuración de Detekt. Por suerte, este problema ya ha sido informado y solucionado La verificación de reglas de omisión con el modo API explícito está activada.

LibraryCodeMustSpecifyReturnType: Esta regla está destinada a controlar el tipo de retorno explícito de las API públicas. Sin embargo, descubrí que la definición de API pública no es necesariamente la misma que la API pública real definida en el compilador de Kotlin. Lo informé problema y la solución se solucionará en la próxima versión. Por ahora, si hemos habilitado el modo de API explícita de Kotlin, no necesitamos mantener esta regla activa.

He enumerado algunos problemas y he proporcionado sus soluciones cuando empiezas a adoptar el modo API explícito en Kotlin. Esta es una característica extremadamente útil y recomendada que haría que los autores de bibliotecas fueran más conscientes de sus API expuestas. Y los autores de bibliotecas pueden estar libres de ser regañados por incompatibilidad con versiones anteriores.

La verbosidad de Java se manifiesta en la necesidad de agregar public y siempre devuelve el tipo. De hecho, esta es una característica bastante buena que hace que el contrato entre la biblioteca y sus dependencias sea explícito. Kotlin inicialmente cambió su comportamiento predeterminado para simplificar el código, pero a costa de oscurecer el contrato. Afortunadamente, este problema se ha solucionado en Kotlin últimamente para estar a la par con Java.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *