被Bug搞疯了?给你的应用嵌入一个Logcat吧
作者:椎锋陷陈
https://www.jianshu.com/u/9bfd80e684ad
前言
allprojects {
repositories {
...
maven{ url "https://dl.bintray.com/madchan/maven" }
}
}
implementation 'com.madchan.library:embeddedlogcat:1.0.0'
startActivity(Intent(this, LogcatActivity::class.java))
https://github.com/madchan/EmbeddedLogcat
正文
知识储备
Verbose:显示所有日志消息(默认值)。 Debug:显示仅在开发期间有用的调试日志消息,以及此列表中较低的消息级别。 Info:显示常规使用情况的预期日志消息,以及此列表中较低的消息级别。 Warn:显示尚不是错误的潜在问题,以及此列表中较低的消息级别。 Error:显示已经引发错误的问题,以及此列表中较低的消息级别。 Assert:显示开发者预计绝不会发生的问题。
Show only selected application:仅显示通过应用代码生成的消息(默认选项)。Logcat 使用正在运行的应用的 PID 来过滤日志消息。 No Filters:不应用过滤器。无论您选择哪个进程,logcat 都会显示设备中的所有日志消息。 Edit Filter Configuration:创建或修改自定义过滤器。例如,您可以创建一个过滤器,以同时查看两个应用中的日志消息。
adb logcat --help
方案实现
data class Command(var level: String = " *:V") { // 级别
var pid: Int? = 0 // 进程ID
var expr: String? = null // 关键词
override fun toString(): String {
val builder = StringBuilder("logcat -d -v time $level")
pid?.let {
builder.append(" --pid=$pid")
}
if (!TextUtils.isEmpty(expr)) {
builder.append(" -e $expr+")
}
return builder.toString()
}
}
adb logcat -d
// LogcatExecutor.kt
...
private fun execOutputCommand(command: Command?) {
try {
val command = command?.toString() ?: "logcat -d"
val process = Runtime.getRuntime().exec(command)
val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
val log = StringBuilder()
var line: String? = bufferedReader.readLine()
while (line != null) {
log.append(line)
log.append("\n\n")
line = bufferedReader.readLine()
}
callback?.onLogOutput(log.toString())
} catch (e: IOException) {
Log.e("LogcatHandler", "执行Logcat命令行失败:" + e.message)
}
}
...
// LogcatActivity.kt
...
private lateinit var process: Spinner
...
process.onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(
adapterView: AdapterView<*>?,
view: View,
position: Int,
l: Long
) {
command.pid = processMap[(process.adapter.getItem(position) as String)]
startOutput()
}
override fun onNothingSelected(adapterView: AdapterView<*>?) {}
}
...
// LogcatActivity.kt
...
private lateinit var level: Spinner
...
level.onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(
adapterView: AdapterView<*>?,
view: View,
i: Int,
l: Long
) {
when (i) {
0 -> command.level = "*:V"
1 -> command.level = "*:D"
2 -> command.level = "*:I"
3 -> command.level = "*:W"
4 -> command.level = "*:E"
else -> {
}
}
startOutput()
}
override fun onNothingSelected(adapterView: AdapterView<*>?) {}
}
...
// LogcatActivity.kt
...
private lateinit var search: EditText
...
search.addTextChangedListener (object : TextWatcher{
override fun afterTextChanged(s: Editable?) {
command.expr = s.toString().trim()
startOutput()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
...
使用场景
https://www.jianshu.com/p/6ae1794d8fca
总结
推荐阅读
• 耗时2年,Android进阶三部曲第三部《Android进阶指北》出版!
推荐我的技术博客
推荐一下我的独立博客: liuwangshu.cn ,内含Android最强原创知识体系,一直在更新,欢迎体验和收藏!
BATcoder技术群,让一部分人先进大厂
你好,我是刘望舒,百度百科收录的腾讯云TVP专家,著有三本技术畅销书,蝉联四届电子工业出版社年度优秀作者,谷歌开发者社区特邀讲师。
前华为面试官,现大厂技术负责人。
欢迎添加我的微信 henglimogan ,备注:BATcoder,加入BATcoder技术群。
明天见(。・ω・。)
评论