一个智能,可靠且高度可自定义的调试菜单库,用于支持屏幕录制,网络活动记录,生成错误报告以及许多其他有用功能。
克隆此存储库,选择一个构建变体并运行应用程序配置。它应该看起来像这样:
该演示应用程序还包含有关如何设置Beagle以及如何实现正在展示的各种功能的说明。如果您有兴趣在项目中使用库,则绝对应该考虑尝试一下。如果您不想自己构建它,也可以从Play商店下载它:
应用程序中的教程涵盖了此读数中的所有内容,但更详细地说明了。本文的另一种了解可以通过库可以实现的方法,该文章提出了可以用Beagle解决的各种问题。
如果下面的文本墙对于您的口味来说太长,请查看包含您需要使用的所有代码的要点。否则,让我们逐步进行:
确保以下是项目级构建的一部分。gradle文件:
allprojects {
repositories {
…
mavenCentral()
}
}
调试菜单的实际UI可以通过多种方式显示,这是由依赖项的后缀指定的。存在以下版本:
DebugMenuView
是您的责任(不建议:摇动打开, Beagle.show()
, Beagle.hide()
,相关的VisibilityListener
,以及插图处理逻辑将无法奏效)。因此,例如,如果您喜欢抽屉UI,则需要将以下内容添加到您的app-level build.gradle文件中(查看最新版本的代码段下方的小部件):
dependencies {
…
def beagleVersion = " 2.9.8 "
debugImplementation " io.github.pandulapeter.beagle:ui-drawer: $b eagleVersion "
releaseImplementation " io.github.pandulapeter.beagle:noop: $b eagleVersion "
}
最新版本是:
注意:对于抽屉UI,如果您已经覆盖了Activity
的onBackPressed()
方法,则可能会注意到默认的后背导航处理并不总是按预期工作。为了解决此问题,在每个Activity
的onBackPressed()
中,您应该检查Beagle.hide()
在执行其他检查或调用超级实现之前返回false。
只有一行代码,最好是在Application
的onCreate()
方法中:
Beagle .initialize( this )
您可以选择地将以下参数添加到此功能:
themeResourceId
属性为“调试菜单”指定一个自定义主题,以防Application
/ Activity
使用的属性不合适。注意:建议扩展.NoActionBar
材料主题。默认情况下,您可以通过摇动设备来获取Beagle。
在此之后,应该提供许多模块,但是可以随时更改此配置(来自任何线程),并且UI将自动更新。这样做的最简单方法是致电:
Beagle .set(module1, module2, …)
在这一点上,您应该知道两个选择:
查看Showcase应用程序,以获取一些有关内置模块或可以用于预览任何模块配置并为其生成代码的交互式工具的想法。本文是一些可能性的视觉指南。
这是一个最小的例子,应该适用于大多数项目:
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 ()
)
如果您需要添加临时模块, Beagle.add()
具有可选的lifecycleOwner
参数,该参数一旦提供的生命周期结束后自动删除指定的模块。使用模块ID-S手动调用Beagle.remove()
也是一个选项。
虽然调用Beagle.log()
是将项目添加到LogListModule的最简单方法,但需要特殊的解决方法才能从纯Kotlin模块访问此功能。另一个频繁的用例是与木材集成。
要访问Beagle.log()
从纯Kotlin / Java模块提供的相同功能,首先,您需要将以下内容添加到所讨论的模块:
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"
}
这些库提供了BeagleLogger
对象,该对象在Application
类中初始化时需要连接到主库:
Beagle .initialize(
…
behavior = Behavior (
…
logBehavior = Behavior . LogBehavior (
loggers = listOf ( BeagleLogger ),
…
)
)
)
要添加日志消息,现在您可以调用以下内容:
BeagleLogger .log(…)
消息列表将与使用常规Beagle.log()
函数记录的消息列表合并(除非它们被标签过滤),并且可以使用loglistModule显示。如果您无法访问BeagleLogger.clearLogEntries()
也可以使用Beagle.clearLogEntries()
。
要自动将带有木材记录的事件添加到调试菜单中,种植一棵特殊树是最简单的解决方案:
Timber .plant(
object : Timber . Tree () {
override fun log ( priority : Int , tag : String? , message : String , t : Throwable ? ) =
Beagle .log( " [ $tag ] $message " , " Timber " , t?.stackTraceToString())
}
)
要创建仅显示这些日志的特殊LogListModule,只需将模块的标签构造函数参数设置为“木材”。
不将网络拦截器与主库捆绑在一起主要是为了提供不使用Android SDK的纯kotlin依赖性,类似于上述记录解决方案。目前,Beagle只能将其连接到OKHTTP网络库中以提供网络loglistModule的内容,但是手动调用Beagle.logNetworkEvent()
始终是一个选项。
将以下内容添加到实现网络逻辑的模块中:
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"
}
这将介绍首先需要连接到主库的BeagleOkHttpLogger
对象,该对象是初始化的那一刻:
Beagle .initialize(
…
behavior = Behavior (
…
networkLogBehavior = Behavior . NetworkLogBehavior (
networkLoggers = listOf ( BeagleOkHttpLogger ),
…
)
)
)
最后一步是设置Interceptor
(尴尬的铸造是为了确保NOOP实现在仍然拥有相同的公共API的同时什么都不做):
val client = OkHttpClient . Builder ()
…
. apply { ( BeagleOkHttpLogger .logger as ? Interceptor ? )?. let { addInterceptor(it) } }
.build()
图书馆可以拦截未取消的例外,并在对话框中显示其堆栈跟踪。用户将能够使用自动打开的错误报告屏幕共享崩溃报告。通过单独的依赖项来实现此功能,该功能应添加到主模块(初始化Beagle):
dependencies {
…
debugImplementation " io.github.pandulapeter.beagle:log-crash: $b eagleVersion "
releaseImplementation " io.github.pandulapeter.beagle:log-crash-noop: $b eagleVersion "
}
添加依赖关系后,新引入的BeagleCrashLogger
对象应连接到主库:
Beagle .initialize(
…
behavior = Behavior (
…
bugReportingBehavior = Behavior . BugReportingBehavior (
crashLoggers = listOf ( BeagleCrashLogger ),
…
)
)
)
与其他崩溃报告解决方案同时使用此功能可能是不可靠的。
另外,请注意,通过引入log-crash
依赖关系,Beagle的错误报告活动现在将在单独的过程中运行(例如,Firebase需要对多进程应用程序进行特殊的初始化调用)。
每个公共工件的noop
实现是不包括与Beagle相关的逻辑中的默认方法。尽管对于大多数项目来说,这应该足够好,但是可以通过为调试菜单创建单独的包装器模块来改进它。这意味着将每个呼叫的呼叫隐藏在一个接口后面,该接口在发行版中具有空的实现。这种方法有其自身的好处和缺点:
noop
伪像Application
类中调用initialize()
函数,并在清单中正确注册该类FragmentActivity
(例如, AppCompatActivity
是一个不错的选择)。提防,如果您使用的是Android Studio的Empty Compose Activity
模板,则必须更改默认的父类!默认情况下,Beagle使用当前Activity
的主题。但是,它需要一个材料主题才能起作用,因此,如果您发现未找到各种主题属性引起的崩溃,请用themeResourceId
属性覆盖调试菜单的主题。
Beagle通过在每个Activity
的布局上添加Fragment
来起作用。有时这是不必要的,也不可能。尽管库带有排除Activity
包名称的列表,但您可以在需要时使用shouldAddDebugMenu
lambda属性,在初始化期间提供的行为实例的属性。
为初始化过程中提供的外观实例的themeResourceId
属性设置一个.NoActionBar
材料主题。
所有公共功能均记录在KDOC中。 BeagleContract文件是学习所有内置功能的良好开始。有关各个模块的信息,请参见相关的类标题。
如果您对引擎盖下的内容感兴趣,则在导航源代码时,本文档可能会有所帮助。
查看每个版本的更改版本页面。
该库使用语义版本操作: Major.minor.patch ,其中补丁更改仅包含错误修复,次要更改添加了新功能和主要更改将为API引入破坏修改。
查看“问题”页面,以获取已知问题列表以及库的计划增强。
如果您发现一个错误或有任何疑问 /功能请求,请随时打开新问题!
如果您发现我的作品有用并正在考虑进行少量捐款,那么Showcase应用程序的大约部分可以选择您这样做。提前致谢!
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.