Uma biblioteca de menus de depuração inteligente, confiável e altamente personalizável para aplicativos Android que suporta gravação de tela, registro de atividades de rede, geração de relatórios de bugs e muitos outros recursos úteis.
Clone this repository, pick a build variant and run the app configuration. Deve parecer algo assim:
Esse aplicativo de demonstração também contém instruções sobre como configurar o Beagle e como implementar os vários recursos que estão sendo exibidos. Definitivamente, você deve considerar experimentá -lo se estiver interessado em usar a biblioteca em seus projetos. Se você não tiver vontade de construí -lo por si mesmo, também pode baixá -lo na Play Store:
Os tutoriais no aplicativo cobrem tudo a partir deste readme, mas com mais detalhes. Outra maneira de ter uma idéia do que pode ser alcançado com a biblioteca é este artigo, que apresenta vários problemas que podem ser resolvidos com Beagle.
Se a parede do texto abaixo for muito longa para o seu gosto, confira esta essência que contém todo o código necessário para uma boa configuração. Caso contrário, vamos fazer isso passo a passo:
Verifique se o seguinte faz parte do seu arquivo Build.gradle no nível do projeto:
allprojects {
repositories {
…
mavenCentral()
}
}
A interface do usuário real do menu Debug pode ser exibida de várias maneiras, o que é especificado pelo sufixo da dependência. Existem as seguintes versões:
DebugMenuView
é de sua responsabilidade (não recomendado: Shake to Open, Beagle.show()
, Beagle.hide()
, o VisibilityListener
relacionado e a lógica de manuseio de inserção não funcionará fora da caixa).Por exemplo, se você preferir a interface do usuário da gaveta, algo como o seguinte precisa ser adicionado ao seu arquivo Build.gradle no nível do aplicativo (verifique o widget abaixo do snippet de código para obter a versão mais recente):
dependencies {
…
def beagleVersion = " 2.9.8 "
debugImplementation " io.github.pandulapeter.beagle:ui-drawer: $b eagleVersion "
releaseImplementation " io.github.pandulapeter.beagle:noop: $b eagleVersion "
}
A versão mais recente é:
NOTA : No caso da interface do usuário da gaveta, se você substituiu o método onBackPressed()
da Activity
, poderá perceber que o manuseio padrão de navegação nas costas nem sempre funciona conforme o esperado. Para corrigir isso, em todas Activity
, onBackPressed()
você deve verificar se o Beagle.hide()
retorna false antes de fazer quaisquer outros cheques ou ligar para a super implementação.
Apenas uma linha de código, de preferência no método onCreate()
do Application
:
Beagle .initialize( this )
Opcionalmente, você pode adicionar os seguintes parâmetros a esta função:
themeResourceId
, caso o usado pelo Application
/ Activity
não seja adequado. NOTA: É recomendável estender um tema de material .NoActionBar
.Por padrão, você pode buscar Beagle agitando o dispositivo.
Depois disso, vários módulos devem ser fornecidos, mas essa configuração pode ser alterada a qualquer momento (de qualquer thread) e a interface do usuário será automaticamente atualizada. A maneira mais simples de fazer isso é chamando:
Beagle .set(module1, module2, …)
Neste ponto, você deve estar ciente de duas opções:
Confira o aplicativo Showcase para algumas idéias sobre o que é possível com os módulos internos ou para uma ferramenta interativa que pode ser usada para visualizar qualquer configuração de módulo e gerar o código para ele. Um guia mais visual para algumas das possibilidades é este artigo.
Aqui está um exemplo mínimo que deve funcionar para a maioria dos projetos:
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 ()
)
Se você precisar adicionar módulos temporários, Beagle.add()
possui um parâmetro opcional lifecycleOwner
que remove automaticamente os módulos especificados assim que o ciclo de vida fornecido terminar. Chamar manualmente Beagle.remove()
com o módulo ID-S também é uma opção.
Enquanto chamando Beagle.log()
é a maneira mais simples de adicionar itens ao loglistmodule, é necessária uma solução alternativa especial para acessar essa funcionalidade dos módulos Kotlin puros. Outro caso de uso frequente é a integração com a madeira.
Para acessar a mesma funcionalidade que Beagle.log()
fornece de um módulo Kotlin / Java puro, primeiro você precisa adicionar o seguinte ao módulo em questão:
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"
}
Essas bibliotecas fornecem o objeto BeagleLogger
, que precisa estar conectado à biblioteca principal quando for inicializado na classe Application
:
Beagle .initialize(
…
behavior = Behavior (
…
logBehavior = Behavior . LogBehavior (
loggers = listOf ( BeagleLogger ),
…
)
)
)
Para adicionar mensagens de log, agora você pode ligar para o seguinte:
BeagleLogger .log(…)
A lista de mensagens será mesclada com aquelas registradas usando a função Beagle.log()
regular (a menos que sejam filtradas por suas tags) e podem ser exibidas usando um loglistmodule. Você também pode usar BeagleLogger.clearLogEntries()
se não puder acessar Beagle.clearLogEntries()
.
Para adicionar automaticamente eventos registrados com madeira ao menu Debug, plantar uma árvore especial é a solução mais simples:
Timber .plant(
object : Timber . Tree () {
override fun log ( priority : Int , tag : String? , message : String , t : Throwable ? ) =
Beagle .log( " [ $tag ] $message " , " Timber " , t?.stackTraceToString())
}
)
Para criar um module de loglist especial que exibe apenas esses logs, basta definir o parâmetro do construtor do rótulo do módulo como "madeira".
Não foi feito o interceptor de rede com a biblioteca principal para fornecer uma dependência pura de Kotlin que não usa o Android SDK, da mesma forma que a solução de logger descrita acima. No momento, Beagle só pode conectar -se à biblioteca de rede OKHTTP para fornecer conteúdo para o NetworkLogListModule, mas chamando manualmente Beagle.logNetworkEvent()
é sempre uma opção.
Adicione o seguinte ao módulo em que sua lógica de rede é implementada:
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"
}
Isso apresentará o objeto BeagleOkHttpLogger
, que primeiro precisa ser conectado à biblioteca principal, no momento em que é inicializado:
Beagle .initialize(
…
behavior = Behavior (
…
networkLogBehavior = Behavior . NetworkLogBehavior (
networkLoggers = listOf ( BeagleOkHttpLogger ),
…
)
)
)
A última etapa está configurando o Interceptor
(o elenco estranho está lá para garantir que a implementação do NOOP não faça nada enquanto ainda tem a mesma API pública):
val client = OkHttpClient . Builder ()
…
. apply { ( BeagleOkHttpLogger .logger as ? Interceptor ? )?. let { addInterceptor(it) } }
.build()
A biblioteca pode interceptar exceções não capturadas e exibir seu rastreamento de pilha em uma caixa de diálogo. Os usuários poderão compartilhar o relatório de falha usando a tela de relatório de bugs que é aberta automaticamente. Essa funcionalidade é alcançada através de uma dependência separada que deve ser adicionada ao módulo principal (onde Beagle é inicializado):
dependencies {
…
debugImplementation " io.github.pandulapeter.beagle:log-crash: $b eagleVersion "
releaseImplementation " io.github.pandulapeter.beagle:log-crash-noop: $b eagleVersion "
}
Depois que as dependências forem adicionadas, o objeto BeagleCrashLogger
recém -introduzido deve ser conectado à biblioteca principal:
Beagle .initialize(
…
behavior = Behavior (
…
bugReportingBehavior = Behavior . BugReportingBehavior (
crashLoggers = listOf ( BeagleCrashLogger ),
…
)
)
)
O uso desse recurso simultaneamente com outras soluções de relatórios de falhas pode não ser confiável.
Além disso, observe que, ao introduzir a dependência log-crash
, a atividade de relatório de bugs da Beagle agora será executada em um processo separado (Firebase, por exemplo, precisa de uma chamada especial de inicialização para aplicativos de vários processos).
As implementações noop
de todos os artefatos públicos são as maneiras padrão de não incluir a lógica relacionada a Beagle em seus lançamentos de produção. Embora isso deva ser bom o suficiente para a maioria dos projetos, ele pode ser aprimorado criando um módulo de wrapper separado para o menu Debug. Isso significaria esconder todas as chamadas para Beagle atrás de uma interface que possui uma implementação vazia nas compilações de liberação. Esta abordagem tem seus próprios benefícios e desvantagens:
noop
em sua configuração atualinitialize()
em sua classe Application
personalizada e que a classe está registrada corretamente no manifestoFragmentActivity
(por exemplo, AppCompatActivity
é uma boa escolha). Cuidado, se você estiver usando o modelo Empty Compose Activity
do Android Studio, precisará alterar a classe pai padrão! Por padrão, Beagle usa o tema da Activity
atual. No entanto, exige que um tema material funcione; portanto, se você tiver uma falha causada por vários atributos de temas que não estão sendo encontrados, substitua o tema do menu de depuração pela propriedade themeResourceId
da instância de aparência fornecida durante a inicialização com um tema material.
Beagle funciona adicionando um Fragment
sobre o layout de todas Activity
. Às vezes isso não é necessário ou não é possível. Embora a biblioteca venha com uma lista de nomes de pacotes Activity
excluídos, você pode fornecer filtragem adicional, se necessário, usando a propriedade shouldAddDebugMenu
lambda da instância de comportamento fornecida durante a inicialização.
Definir um tema de material .NoActionBar
para a propriedade themeResourceId
da instância de aparência fornecida durante a inicialização.
Todas as funções públicas estão documentadas com o KDOC. O arquivo BeAGleContract é um bom começo para aprender sobre todos os recursos internos. Para obter informações sobre os módulos individuais, consulte os cabeçalhos de classe relevantes.
Se você estiver interessado no que está sob o capô, este documento pode ser útil ao navegar no código -fonte.
Confira a página de lançamentos para obter as alterações em todas as versões.
A biblioteca usa versão semântica: major.Minor.patch , onde as alterações do patch contêm apenas correções de bug, pequenas alterações adicionam novos recursos e grandes alterações introduzem modificações de quebra na API.
Confira a página de problemas da lista de problemas conhecidos e dos aprimoramentos planejados da biblioteca.
Não hesite em abrir um novo problema se encontrar um bug ou se tiver alguma dúvida / solicitação de recurso!
Se você achou meu trabalho útil e está considerando uma pequena doação, a seção Sobre o aplicativo Showcase tem uma opção para você fazê -lo. Desde já, obrigado!
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.