使用案例
"打印测试".log();
123.log();
null.toString().log();
打印输出内容
普通文本输出结果
flutter:
=========================开始===========================
文件路径:package:flutter_component/page/demo/notification_center_page.dart
相关信息:_State._contentView.<anonymous closure> -> 46行
输出内容:打印测试
=========================结束===========================
flutter:
=========================开始===========================
文件路径:package:flutter_component/page/demo/notification_center_page.dart
相关信息:_State._contentView.<anonymous closure> -> 47行
输出内容:123
=========================结束===========================
flutter:
=========================开始===========================
文件路径:package:flutter_component/page/demo/notification_center_page.dart
相关信息:_State._contentView.<anonymous closure> -> 48行
输出内容:null
=========================结束===========================
源码
extension StringExtension on String {
/// 打印
void log({CustomTrace info}) {
info ??= CustomTrace(StackTrace.current);
if (info?.filePath != null) {
LogUtil.v(
"文件路径:${info.filePath}\n相关信息:${info.methodName} -> ${info.lineNumber}行 \n输出内容:$this");
} else {
print(
"\n=========================开始===========================\ncontent:$this\n=========================结束===========================");
}
}
}
extension ObjectExtension on Object {
void lod() {
String string = this.toString();
string.log(info: CustomTrace(StackTrace.current));
}
}
class CustomTrace {
final StackTrace _trace;
/// 行号
int lineNumber;
/// 列号(没啥用)
int columnNumber;
/// 文件路径
String filePath;
/// 方法名
String methodName = "";
CustomTrace(this._trace) {
_parseTrace();
}
void _parseTrace() {
var list = this._trace.toString().split("\n");
var traceString = list.first;
if (list.length > 1) traceString = list[1]; // 有多个时去掉扩展这一层
/// 过滤特殊符号
traceString = traceString.replaceAll("#1 ", "");
traceString = traceString.replaceAll(")", "");
var info = traceString.split(" (");
/// 方法名
methodName = info.first;
var pathInfo = info.last;
try {
var tmp = pathInfo.split(":");
if (tmp.last is int) {
/// 列号
columnNumber = int.parse(tmp.last.toString());
}
tmp.removeLast();
if (tmp.last is int) {
/// 行号
lineNumber = int.parse(tmp.last.toString());
}
tmp.removeLast();
/// 文件路径
filePath = tmp.join(":");
} catch (e) {
filePath = pathInfo;
}
// print("\n列号:${columnNumber}\n行号:${lineNumber}\n文件路径:${filePath}");
}
}
class LogUtil {
static int _limitLength = 900;
static void init({int limitLength}) {
_limitLength = limitLength ??= _limitLength;
}
static void v(dynamic obj) {
_log(obj.toString());
}
static void _log(String msg) {
var tmp =
"\n=========================开始===========================\n${msg}\n=========================结束===========================\n";
if (tmp.length < _limitLength) {
print(tmp);
} else {
segmentationLog(tmp);
}
}
static void segmentationLog(String msg) {
var outStr = StringBuffer();
for (var index = 0; index < msg.length; index++) {
outStr.write(msg[index]);
if (index % _limitLength == 0 && index != 0) {
outStr.clear();
var lastIndex = index + 1;
if (msg.length - lastIndex < _limitLength) {
var remainderStr = msg.substring(lastIndex, msg.length);
print(remainderStr);
break;
}
}
}
}
}
踩坑(因为刚学Flutter 代码啥的都是百度的)
因为是扩展越简单越方便 怎么简单怎么来 那么我们想获取的信息可能会存在异常 如下:
从使用上来说 每次都需要携带StackTrace.current
堆栈信息是比较麻烦的所以我将其写在了方法内部 但是问题来了 这样获取的最前面一个信息是当前的扩展信息
CustomTrace info = CustomTrace(StackTrace.current);
百度方法打印
void _parseTrace() {
var list = this._trace.toString().split("\n");
var traceString = list.first;
var indexOfFileName = traceString.indexOf(RegExp(r'[A-Za-z_]+.dart'));
var fileInfo = traceString.substring(indexOfFileName);
var listOfInfos = fileInfo.split(":");
this.fileName = listOfInfos[0];
this.lineNumber = int.parse(listOfInfos[1]);
var columnStr = listOfInfos[2];
columnStr = columnStr.replaceFirst(")", "");
this.columnNumber = int.parse(columnStr);
}
输出一直异常 一直定位到扩展
flutter:
=========================开始===========================
文件: extension.dart -> 9行
内容: 参数:{}
=========================结束===========================
我们来打印信息看看
void _parseTrace() {
print(this._trace.toString()); // 打印信息
...
}
输出结果(从以下结果可以看出最前面一个一直会是我们的扩展, 而真实想要的信息是第二个)
flutter:
#0 StringExtension.log (package:flutter_demo/extension/extension.dart:9:47)
#1 _MyAppState.routeFactory (package:flutter_demo/main.dart:55:32)
#2 routeFactoryWrapper.<anonymous closure> (package:flutter_boost/src/boost_navigator.dart:17:29)
#3 BoostPage.create (package:flutter_boost/src/flutter_boost_app.dart:638:55)
#4 new BoostContainer (package:flutter_boost/src/boost_container.dart:14:26)
#5 FlutterBoostAppState._createContainer (package:flutter_boost/src/flutter_boost_app.dart:178:12)
#6 FlutterBoostAppState.initState (package:flutter_boost/src/flutter_boost_app.dart:91:9)
#7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4723:57)
#8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4556:5)
#9 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3631:14)
#10 Element.updateChild (package:flutter/src/widgets/framework.dart:3383:18)
#11 ComponentElement.performRebuil<…>
改进写法(把自己这一层排除掉OK)
void _parseTrace() {
var list = this._trace.toString().split("\n");
var traceString = list.first;
if (list.length > 1) traceString = list[1]; // 有多个时去掉扩展这一层
var indexOfFileName = traceString.indexOf(RegExp(r'[A-Za-z_]+.dart'));
var fileInfo = traceString.substring(indexOfFileName);
print("打印" + this._trace.toString());
var listOfInfos = fileInfo.split(":");
this.fileName = listOfInfos[0];
this.lineNumber = int.parse(listOfInfos[1]);
var columnStr = listOfInfos[2];
columnStr = columnStr.replaceFirst(")", "");
this.columnNumber = int.parse(columnStr);
}