Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: Setprop To Log and Quick Test #71

Open
yunshuipiao opened this issue Dec 6, 2019 · 0 comments
Open

Android: Setprop To Log and Quick Test #71

yunshuipiao opened this issue Dec 6, 2019 · 0 comments
Labels

Comments

@yunshuipiao
Copy link
Owner

yunshuipiao commented Dec 6, 2019

[TOC]

日志

每一个Android App 都会有自己的日志系统。

推荐将日志模块放在工具类模块中,不要出现一个项目中存在多个日志工具类的情况。

如果是 sdk ,将日志模块的可见性设为模块内可见。

一般都会对日志进行封装,加上自定义的tag。如下

object LogTest {

    val tag = "LogTest"

    fun d(msg: String) {
        this.d(tag, msg)
    }
    
    fun d(tag: String, msg: String) {
        if (tag.isBlank()) {
            // 或者第三方日志工具
            Log.d(this.tag, msg)
        } else {
            Log.d(tag, msg)
        }
    }
}

接着需要控制何时对日志进行输入,比如常见的在 Debug 下输出,Release 下不输出。

常见的有三种方式:

Debug 变量控制

可以使用一个变量来控制是否输出日志。如下:

private var debug = true

fun d(tag: String, msg: String) {
    if (debug) {
        val t = if (tag.isBlank()) this.tag else tag
        Log.d(t, msg)
    }
}

缺点:每次发布都需要修改变量值来控制,麻烦且容易出错,淘汰。

BuildConfig.DEBUG 控制

private var debug = BuildConfig.DEBUG

由 BuildConfig.DEBUG 来动态控制,不需手动修改。

缺点:上面提到,将日志工具类放在底层工具模块中,此时 BuildConfig.DEBUG 的值永远为 false,日志无法输出。只有在 app 模块中,BuildConfig.DEBUG 值才能根据 Debug 和 Release 版本控制。淘汰

ApplicationInfo 的 flag 控制

isDebug = (application.applicationInfo.flags
        and ApplicationInfo.FLAG_DEBUGGABLE) != 0

可以使用上述的 debug 值来控制。并且推荐将改值放在底层工具类中,支持整个项目使用。

setprop

在 adb shell 的命令中,有一对命令

adb shell setprop [key] [value]
adb shell getprop [key]

可以设置系统属性和读取系统属性。

其中 adb shell setprop log.tag.x DEBUG 这个命令设置系统属性。

Log.isLogger(tag, leval) 的返回值是 boolean 类型,来控制日志输出。

其中 log.tag.x 为key, x表示自定义的tag,DEBUG(V, D, I, E) 表示日志级别(默认为 INFO)。

只有当 Log.isLogger(tag, leval) 的 tag 相等, leval 大于等于 命令行设置的参数是,才进行日志输出。

所以日志输出的最终方案为:

val tag = "LogTest"

private var debug = SwUtils.isDebug
private var propDebug = Log.isLoggable(tag, Log.DEBUG)

fun d(tag: String, msg: String) {
    if (debug || propDebug) {
        val t = if (tag.isBlank()) this.tag else tag
        Log.d(t, msg)
    }
}

通过参数来控制日志输出。

好处:Debug 模式下进行日志输出。

Release 模式下默认不输出日志。当需要日志时,终端下adb shell log.tag.LogTest DEBUG即可输出日志。

快速测试

接着上面的 setprop,可以自定义系统属性的key,value。那么在需要时就可以通过命令行终端修改系统属性,Android 程序读取该属性。

对于需要不断修改某个变量,重新构建打包安装测试的场景来说,可以节省大量的时间。

object SystemPropUtils {

    fun getProp(key: String): String {
        var result = ""
        try {
            val process = Runtime.getRuntime().exec("getprop log.tag.$key")
            result = process.inputStream.bufferedReader().readLine()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return result
    }
}

该方法可以读取 log.tag.key 的系统属性,需要修改时可以通过 adb shell setprop log.tag.key value 来设置,大大加快测试。

疑问:

adb shell setptop key value 。当 key 为任意值时会报错,有系统层开发的大神可以帮忙解决下这个疑问吗?

@yunshuipiao yunshuipiao changed the title Android: Setprop To Log and Hotload Android: Setprop To Log and Quick Test Dec 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant