目录
- [一、Flutter Dart 代码混淆](#一、Flutter Dart 代码混淆)
- [二、Flutter Dart 代码解混淆](#二、Flutter Dart 代码解混淆)
-
- [1、使用 flutter symbolize 解混淆](#1、使用 flutter symbolize 解混淆)
- 2、解混淆后的日志
Dart 代码混淆(Obfuscation)可以 防止反编译和代码泄露,但也会导致 崩溃日志难以阅读。因此,在启用混淆的同时,我们需要保留调试符号文件(symbol files),以便后续 解混淆(Symbolization)。
一、Flutter Dart 代码混淆
1、启用混淆
针对Android,Flutter 在 release 构建时可以启用 Dart 代码混淆:
powershell
flutter build apk --release --obfuscate --split-debug-info=./symbols/
或者针对 iOS:
powershell
flutter build ios --obfuscate --split-debug-info=./symbols/
参数说明:
参数 | 作用 |
---|---|
--obfuscate |
开启 Dart 代码混淆(会混淆类名、方法名等) |
--split-debug-info=./symbols/ |
存储生成的符号表,避免混淆后无法解读堆栈信息,symbols 为生成的符号表目录 |
2、符号表文件
运行上述命令后,symbols
目录中会生成符号表文件,以Android为例:
powershell
debug_info/
├── app.android-arm.symbols
├── app.android-arm64.symbols
├── app.android-x64.symbols
这些 symbols
文件用于解混淆崩溃日志。

二、Flutter Dart 代码解混淆
如果应用因为 dart
代码导致崩溃,堆栈日志可能是这样的:
java
#00 abs 0000006febe81e6b virt 000000000025ee6b _kDartIsolateSnapshotInstructions+0x1288eb
#01 abs 0000006febecd6d7 virt 00000000002aa6d7 _kDartIsolateSnapshotInstructions+0x174157
#02 abs 0000006febed08c3 virt 00000000002ad8c3 _kDartIsolateSnapshotInstructions+0x177343
#03 abs 0000006fec07ea37 virt 000000000045ba37 _kDartIsolateSnapshotInstructions+0x3254b7
#04 abs 0000006fec02781f virt 000000000040481f _kDartIsolateSnapshotInstructions+0x2ce29f
#05 abs 0000006febfce6ab virt 00000000003ab6ab _kDartIsolateSnapshotInstructions+0x27512b
#06 abs 0000006febfce43b virt 00000000003ab43b _kDartIsolateSnapshotInstructions+0x274ebb
#07 abs 000
1、使用 flutter symbolize 解混淆
我们需要用 flutter
自带的 symbolize
命令,解码混淆日志:
powershell
# 格式
flutter symbolize -i [stack_trace_file] -d [symbols_file] > [out_file]
# 例如
flutter symbolize -i /Users/xxx/crash.txt -d /Users/xxx/app.android-arm64.symbols > out.txt
参数说明:
参数 | 说明 |
---|---|
-i [stack_trace_file] |
将需要解混淆的 Dart 代码拷贝到文件中,例如 crash.txt |
-d [symbols_file] |
指定 Flutter 生成的符号表文件,注意要制定对应架构的解码文件 |
> [out_file] |
解码后的堆栈输出到 out_file 文件中 |
2、解混淆后的日志
解码后,你会得到可读的崩溃日志:
java
#0 FlutterCrashPageState.build.<anonymous closure> (/Users/xxx/flutter-mobile-demo/lib/crash/FlutterCrashPage.dart:28:17)
#1 _InkResponseState.handleTap (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/material/ink_well.dart:1183:21)
#2 _InkResponseState.handleTap (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/material/ink_well.dart:1175:3)
#3 new _GrowableList._literal1 (third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart:558:22)
#4 new _ErrorDiagnostic (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/foundation/assertions.dart:178:18)
#5 new ErrorDescription (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/foundation/assertions.dart:271:37)
#6 GestureRecognizer.invokeCallback (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/gestures/recognizer.dart:329:18)
#7 TapGestureRecognizer.handleTapUp (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/gestures/tap.dart)
#8 BaseTapGestureRecognizer._checkUp (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/gestures/tap.dart:310:5)
#9 BaseTapGestureRecognizer.handlePrimaryPointer (/Users/xxx/flutter_3.19.5/packages/flutter/lib/src/gestures/tap.dart:244:7)
#07 abs 000
这就恢复了 原始类名和方法名,可以用于 分析和修复 Bug。