Una biblioteca de menú de depuración inteligente, confiable y altamente personalizable para aplicaciones de Android que admite la grabación de pantalla, el registro de actividades de red, la generación de informes de errores y muchas otras características útiles.
Clone este repositorio, elija una variante de compilación y ejecute la configuración de la aplicación . Debería verse algo así:
Esta aplicación de demostración también contiene instrucciones sobre cómo configurar Beagle y cómo implementar las diversas características que se muestran. Definitivamente debe considerar probarlo si está interesado en usar la biblioteca en sus proyectos. Si no tiene ganas de construirlo por usted mismo, también puede descargarlo desde Play Store:
Los tutoriales en la aplicación cubren todo, desde este readme, pero con más detalle. Otra forma de tener una idea de lo que se puede lograr con la biblioteca es este artículo, que presenta varios problemas que se pueden resolver con Beagle.
Si la pared de texto a continuación es demasiado larga para su gusto, consulte esta esencia que contiene todo el código que necesita para una buena configuración. De lo contrario, hagámoslo paso a paso:
Asegúrese de que lo siguiente sea parte de su archivo Build.gradle a nivel de proyecto:
allprojects {
repositories {
…
mavenCentral()
}
}
La interfaz de usuario real del menú de depuración se puede mostrar de múltiples maneras, que se especifica mediante el sufijo de la dependencia. Existen las siguientes versiones:
DebugMenuView
es su responsabilidad (no recomendado: Agite para abrir, Beagle.show()
, Beagle.hide()
, el VisibilityListener
relacionado y la lógica de manejo de inserción no funcionarán fuera de la caja).Entonces, por ejemplo, si prefiere la interfaz de usuario del cajón, se debe agregar algo como lo siguiente a su archivo Build.gradle de nivel de aplicación (verifique el widget debajo del fragmento de código para obtener la última versión):
dependencies {
…
def beagleVersion = " 2.9.8 "
debugImplementation " io.github.pandulapeter.beagle:ui-drawer: $b eagleVersion "
releaseImplementation " io.github.pandulapeter.beagle:noop: $b eagleVersion "
}
La última versión es:
Nota : En el caso de la interfaz de usuario del cajón, si ha sobrescribido el método onBackPressed()
de Activity
, puede notar que el manejo predeterminado de navegación posterior no siempre funciona como se esperaba. Para solucionar esto, en onBackPressed()
de cada Activity
debe verificar que Beagle.hide()
devuelva falso antes de hacer cualquier otro cheque o llamar a la super implementación.
Solo una línea de código, preferiblemente en el método onCreate()
de Application
:
Beagle .initialize( this )
Opcionalmente puede agregar los siguientes parámetros a esta función:
themeResourceId
, en caso de que el utilizado por la Application
/ Activity
no sea adecuada. NOTA: Se recomienda extender un tema de material .NoActionBar
.Por defecto, puede obtener Beagle agitando el dispositivo.
Después de esto, se deben proporcionar varios módulos, pero esta configuración se puede cambiar en cualquier momento (desde cualquier hilo) y la interfaz de usuario se actualizará automáticamente. La forma más sencilla de hacer esto es llamar:
Beagle .set(module1, module2, …)
En este punto, debe conocer dos opciones:
Consulte la aplicación Showcase para ver algunas ideas sobre lo que es posible con los módulos incorporados o para una herramienta interactiva que pueda usarse para obtener una vista previa de cualquier configuración del módulo y generar el código para ello. Una guía más visual para algunas de las posibilidades es este artículo.
Aquí hay un ejemplo mínimo que debería funcionar para la mayoría de los proyectos:
Beagle .set(
HeaderModule (
title = getString( R .string.app_name),
subtitle = BuildConfig . APPLICATION_ID ,
text = " ${ BuildConfig . BUILD_TYPE } v ${ BuildConfig . VERSION_NAME } ( ${ BuildConfig . VERSION_CODE } ) "
),
AppInfoButtonModule (),
DeveloperOptionsButtonModule (),
PaddingModule (),
TextModule ( " General " , TextModule . Type . SECTION_HEADER ),
KeylineOverlaySwitchModule (),
AnimationDurationSwitchModule (),
ScreenCaptureToolboxModule (),
DividerModule (),
TextModule ( " Logs " , TextModule . Type . SECTION_HEADER ),
NetworkLogListModule (), // Might require additional setup, see below
LogListModule (), // Might require additional setup, see below
LifecycleLogListModule (),
DividerModule (),
TextModule ( " Other " , TextModule . Type . SECTION_HEADER ),
DeviceInfoModule (),
BugReportButtonModule ()
)
Si alguna vez necesita agregar módulos temporales, Beagle.add()
tiene un parámetro lifecycleOwner
opcional que elimina automáticamente los módulos especificados una vez que termina el ciclo de vida proporcionado. Llamar manualmente Beagle.remove()
con el módulo ID-S también es una opción.
Si bien llamar a Beagle.log()
es la forma más simple de agregar elementos a LogListModule, se necesita una solución especial para acceder a esta funcionalidad desde los módulos Kotlin puros. Otro caso de uso frecuente es la integración con la madera.
Para acceder a la misma funcionalidad que Beagle.log()
proporciona desde un módulo Kotlin / Java puro, primero debe agregar lo siguiente al módulo en cuestión:
dependencies {
…
api " io.github.pandulapeter.beagle:log: $b eagleVersion "
// Alternative for Android modules:
// debugApi "io.github.pandulapeter.beagle:log:$beagleVersion"
// releaseApi "io.github.pandulapeter.beagle:log-noop:$beagleVersion"
}
Estas bibliotecas proporcionan el objeto BeagleLogger
que debe conectarse a la biblioteca principal cuando se inicializa en la clase Application
:
Beagle .initialize(
…
behavior = Behavior (
…
logBehavior = Behavior . LogBehavior (
loggers = listOf ( BeagleLogger ),
…
)
)
)
Para agregar mensajes de registro, ahora puede llamar a lo siguiente:
BeagleLogger .log(…)
La lista de mensajes se fusionará con las registradas utilizando la función Beagle.log()
regular (a menos que se filtren por sus etiquetas) y se pueden mostrar usando un LogListModule. También puede usar BeagleLogger.clearLogEntries()
si no puede acceder a Beagle.clearLogEntries()
.
Para agregar automáticamente eventos que se registran con Timber al menú de depuración, plantar un árbol especial es la solución más simple:
Timber .plant(
object : Timber . Tree () {
override fun log ( priority : Int , tag : String? , message : String , t : Throwable ? ) =
Beagle .log( " [ $tag ] $message " , " Timber " , t?.stackTraceToString())
}
)
Para crear un LogListModule especial que solo muestre estos registros, simplemente establezca el parámetro del constructor de etiquetas del módulo en "Timber".
No agrupar el interceptor de red con la biblioteca principal se realizó principalmente para proporcionar una dependencia pura de Kotlin que no usa el SDK de Android, de manera similar a la solución del registrador descrita anteriormente. Por el momento, Beagle solo puede conectarse a la biblioteca de redes OKHTTP para proporcionar contenido para NetworkLogListModule, pero llamar manualmente Beagle.logNetworkEvent()
siempre es una opción.
Agregue lo siguiente al módulo donde se implementa su lógica de red:
dependencies {
…
api " io.github.pandulapeter.beagle:log-okhttp: $b eagleVersion "
// Alternative for Android modules:
// debugApi "io.github.pandulapeter.beagle:log-okhttp:$beagleVersion"
// releaseApi "io.github.pandulapeter.beagle:log-okhttp-noop:$beagleVersion"
}
Esto introducirá el objeto BeagleOkHttpLogger
que primero debe conectarse a la biblioteca principal, en el momento en que se inicializa:
Beagle .initialize(
…
behavior = Behavior (
…
networkLogBehavior = Behavior . NetworkLogBehavior (
networkLoggers = listOf ( BeagleOkHttpLogger ),
…
)
)
)
El último paso es configurar el Interceptor
(el lanzamiento incómodo está ahí para asegurarse de que la implementación de NOOP no haga nada mientras aún tiene la misma API pública):
val client = OkHttpClient . Builder ()
…
. apply { ( BeagleOkHttpLogger .logger as ? Interceptor ? )?. let { addInterceptor(it) } }
.build()
La biblioteca puede interceptar excepciones no capturas y mostrar su rastro de pila en un diálogo. Los usuarios podrán compartir el informe de bloqueo utilizando la pantalla de informes de errores que se abre automáticamente. Esta funcionalidad se logra a través de una dependencia separada que debe agregarse al módulo principal (donde se inicializa Beagle):
dependencies {
…
debugImplementation " io.github.pandulapeter.beagle:log-crash: $b eagleVersion "
releaseImplementation " io.github.pandulapeter.beagle:log-crash-noop: $b eagleVersion "
}
Después de agregar las dependencias, el objeto BeagleCrashLogger
recientemente introducido debe conectarse a la biblioteca principal:
Beagle .initialize(
…
behavior = Behavior (
…
bugReportingBehavior = Behavior . BugReportingBehavior (
crashLoggers = listOf ( BeagleCrashLogger ),
…
)
)
)
El uso de esta función simultáneamente con otras soluciones de informes de choque puede ser poco confiable.
Además, tenga en cuenta que mediante la introducción de la dependencia log-crash
, la actividad de informes de errores de Beagle ahora se ejecutará en un proceso separado (Firebase, por ejemplo, necesita una llamada de inicialización especial para aplicaciones de procesos múltiples).
Las implementaciones noop
de cada artefacto público son las formas predeterminadas de no incluir la lógica relacionada con Beagle en sus lanzamientos de producción. Si bien esto debería ser lo suficientemente bueno para la mayoría de los proyectos, se puede mejorar creando un módulo de envoltura separado para el menú de depuración. Esto significaría ocultar cada llamada a Beagle detrás de una interfaz que tiene una implementación vacía en las compilaciones de lanzamiento. Este enfoque tiene sus propios beneficios y inconvenientes:
noop
en su configuración actualinitialize()
en su clase Application
personalizada, y esa clase está correctamente registrada en el manifiestoFragmentActivity
(por ejemplo, AppCompatActivity
es una buena opción). Tenga cuidado, si está utilizando la plantilla Empty Compose Activity
de Android Studio, ¡debe cambiar la clase principal predeterminada! Por defecto, Beagle usa el tema de Activity
actual. Sin embargo, requiere un tema material para funcionar, por lo que si tiene un bloqueo causado por varios atributos del tema que no se encuentran, anule el tema del menú de depuración con la propiedad themeResourceId
de la instancia de apariencia proporcionada durante la inicialización con un tema material.
Beagle funciona agregando un Fragment
además del diseño de cada Activity
. A veces esto no es necesario o no es posible. Si bien la biblioteca viene con una lista de nombres de paquetes Activity
excluidos, puede proporcionar un filtrado adicional si es necesario, mediante el uso de la propiedad Lambda de la instancia de shouldAddDebugMenu
proporcionada durante la inicialización.
Establezca un tema de material .NoActionBar
para la propiedad themeResourceId
de la instancia de apariencia proporcionada durante la inicialización.
Todas las funciones públicas se documentan con KDOC. El archivo de Beglecontract es un buen comienzo para aprender sobre todas las capacidades incorporadas. Para obtener información sobre los módulos individuales, consulte los encabezados de clase relevantes.
Si está interesado en lo que hay debajo del capó, este documento puede ser útil al navegar por el código fuente.
Consulte la página de versiones para ver los cambios en cada versión.
La biblioteca utiliza versiones semánticas: major.minor.patch donde los cambios de parche solo contienen correcciones de errores, cambios menores agregan nuevas características y cambios importantes introducen modificaciones de ruptura en la API.
Consulte la página de problemas para ver la lista de problemas conocidos y para las mejoras planificadas de la biblioteca.
¡No dude en abrir un nuevo problema si encuentra un error o si tiene alguna pregunta / solicitud de funciones!
Si encontró mi trabajo útil y está considerando una pequeña donación, la sección Acerca de la aplicación Showcase tiene una opción para que lo haga. ¡Gracias de antemano!
Copyright 2022 Pandula Péter
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.