日志模块封封装:单例模式+策略模式+构建者模式+bugly
- 一.单例模式+策略模式+构建者模式
- 二.日志模块封装
- 1.日志等级:LoggerLevel枚举类
- 2.日志输出类型:LoggerType枚举类
- 3.ILogger接口
- 4.LogCatLogger/FileLogger/NetWorkLogger/EmailLogger
- 5.使用构建者模式创建对应的logger对象
- 6.最后使用
- 三.bugly的使用
- 1.什么是Bugly
- 2.集成Bugly
- 3.如何创建Bugly产品
- 4.面试问题难点:如果项目混淆后如何准确定位到错误的信息
一.单例模式+策略模式+构建者模式
设计模式传送门
二.日志模块封装
默认情况下我们的日志只能打印输出,没有永久保存,这里我们的日志不仅能log输出还要能上传到网络,邮件或者本地存储,下面我们进行简单的封装,这里涉及到kotlin基础以及单例模式/策略模式/构建者模式
1.日志等级:LoggerLevel枚举类
/**
* @Author : ytx
* @Time : On 2023/5/21 15:23
* @Description : LoggerLevel 日志等级
*/
enum class LoggerLevel(var value: Int) {
Verbose(1),
Debug(2),
Info(3),
Warn(4),
Error(5)
}
2.日志输出类型:LoggerType枚举类
/**
* @Author : ytx
* @Time : On 2023/5/21 15:36
* @Description : LoggerType 日志输出类型:logcat/文件/邮件/网络
*/
enum class LoggerType {
LOGCAT,FILE,EMAIL,NET
}
3.ILogger接口
/**
* @Author : ytx
* @Time : On 2023/5/21 15:18
* @Description : ILogger:所有logger顶层接口
*/
interface ILogger {
fun d(tag:String,log:String)
fun v(tag:String,log:String)
fun i(tag:String,log:String)
fun w(tag:String,log:String)
fun e(tag:String,log:String)
/**
* 是否Debug,开发阶段为true,上线阶段为false
*/
fun setDebug(isDeug:Boolean)
/**
* 默认TAG
*/
fun setLogTAG(TAG:String)
/**
* 默认日志等级
*/
fun setLoggerLevel(level:LoggerLevel)
/**
* Log存储位置,可以是本地路径 可以是网络路径 可以是Email地址
*/
fun setSaveUrl(url:String)
}
4.LogCatLogger/FileLogger/NetWorkLogger/EmailLogger
创建logger包,下面分别对应4种不同方式,以LogCatLogger为案例
/**
* @Author : ytx
* @Time : On 2023/5/21 15:26
* @Description : LogcatLogger:打印输出log
*/
class LogcatLogger: ILogger {
private var isDebug = true
private var TAG = ""
private var level = LoggerLevel.Debug
private var loggerFormat = "(:=>$TAG %s -->%s"
private var url = ""
override fun d(tag: String, log: String) {
if(isDebug && level.ordinal >= LoggerLevel.Debug.ordinal){
Log.d(TAG,String.format(loggerFormat,tag,log))
}
}
override fun v(tag: String, log: String) {
if(isDebug && level.ordinal >= LoggerLevel.Verbose.ordinal){
Log.v(TAG,String.format(loggerFormat,tag,log))
}
}
override fun i(tag: String, log: String) {
if(isDebug && level.ordinal >= LoggerLevel.Info.ordinal){
Log.i(TAG,String.format(loggerFormat,tag,log))
}
}
override fun w(tag: String, log: String) {
if(isDebug && level.ordinal >= LoggerLevel.Warn.ordinal){
Log.w(TAG,String.format(loggerFormat,tag,log))
}
}
override fun e(tag: String, log: String) {
if(isDebug && level.ordinal >= LoggerLevel.Error.ordinal){
Log.e(TAG,String.format(loggerFormat,tag,log))
}
}
override fun setDebug(isDebug: Boolean) {
this.isDebug = isDebug
}
override fun setLogTAG(TAG: String) {
this.TAG = TAG
}
override fun setLoggerLevel(level: LoggerLevel) {
this.level = level
}
override fun setSaveUrl(url: String) {
this.url = url
}
}
5.使用构建者模式创建对应的logger对象
/**
* @Author : ytx
* @Time : On 2023/5/21 15:37
* @Description : Logger创建对应的logger对象
*/
class Logger private constructor (private val TAG:String, private val level:LoggerLevel,private val loggerType: LoggerType, private val isDebug:Boolean, private val saveUrl:String) {
private var logger:ILogger
init {
logger = getLogger()
}
/**
* 创建Logger
*/
fun getLogger():ILogger{
when(loggerType){
LoggerType.EMAIL -> throw IllegalArgumentException("该方案未实现")
LoggerType.FILE -> throw IllegalArgumentException("该方案未实现")
LoggerType.NET -> throw IllegalArgumentException("该方案未实现")
LoggerType.LOGCAT -> logger = LogcatLogger()
}
logger.setLoggerLevel(level)
logger.setLogTAG(TAG)
logger.setDebug(isDebug)
logger.setSaveUrl(saveUrl)
return logger
}
/**
* 输出Debug log
*/
fun d(Tag:String,log:String){
logger.d(Tag,log)
}
/**
* 输出Warn log
*/
fun w(Tag:String,log:String){
logger.w(Tag,log)
}
/**
* 输出Verbose log
*/
fun v(Tag:String,log:String){
logger.v(Tag,log)
}
/**
* 输出Error log
*/
fun e(Tag:String,log:String){
logger.e(Tag,log)
}
/**
* 输出Info log
*/
fun i(Tag:String,log:String){
logger.i(Tag,log)
}
class Builder(private var TAG:String = "", var level:LoggerLevel = LoggerLevel.Debug, private var loggerType: LoggerType = LoggerType.LOGCAT, var isDebug:Boolean = true, private var saveUrl:String = "" ){
fun setTAG(TAG:String):Builder{
this.TAG = TAG
return this
}
fun setLevel(level:LoggerLevel):Builder{
this.level = level
return this
}
fun setLoggerType(loggerType: LoggerType):Builder{
this.loggerType = loggerType
return this
}
fun isDebug(isDebug: Boolean):Builder{
this.isDebug = isDebug
return this
}
fun setSaveUrl(saveUrl: String):Builder{
this.saveUrl = saveUrl
return this
}
fun build():Logger{
return Logger(
TAG,
level,
loggerType,
isDebug,
saveUrl
)
}
}
}
6.最后使用
var logger = Logger.Builder()
.setLevel(LoggerLevel.Error)
.setLoggerType(LoggerType.LOGCAT)
.isDebug(false)//true打印 false不打印
.setTAG("2010")
.build()
logger.e("MainActivity","hahaha")
可以使用单例模式对log日志的进一步封装
三.bugly的使用
1.什么是Bugly
腾讯Bugly,为移动开发者提供专业的异常上报和运营统计,帮助开发者快速发现并
解决异常,同时掌握产品运营动态,及时跟进用户反馈。
2.集成Bugly
https://bugly.qq.com/docs/user-guide/instruction-manual-android/?v=1.0.0
3.如何创建Bugly产品
https://bugly.qq.com/v2/workbench/apps
4.面试问题难点:如果项目混淆后如何准确定位到错误的信息
使用mapping和符号表上传工具