Skip to content

Commit 9df26ed

Browse files
committed
1.add dump_kernel.dart.snapshot
2.fix bug mixin not work sometimes 3.add mixin demo
1 parent cf46bb7 commit 9df26ed

9 files changed

Lines changed: 351 additions & 33 deletions

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ flutter_macos_stable/bin/cache/dart-sdk/bin/snapshots/frontend_server.dart.snaps
2121
# 编译方式
2222
dart --deterministic --no-sound-null-safety --packages=rebased_package_config.json --snapshot=frontend_server.dart.snapshot --snapshot-kind=kernel lib/starter.dart
2323

24+
dart --deterministic --no-sound-null-safety --packages=rebased_package_config.json --snapshot=dump_kernel.dart.snapshot --snapshot-kind=kernel lib/dump_kernel.dart
25+
2426
# 测试编译
2527
1. 生成kernel_snapshot.d,先用普通方法run一下example,在example/.dart_tool/flutter_build下面会有生成编译临时的文件
2628

@@ -31,17 +33,23 @@ dart --deterministic --no-sound-null-safety --packages=rebased_package_config.js
3133
## 编译aot dill
3234
dart run frontend_server.dart.snapshot --sdk-root /Users/lixin/Documents/flutter_macos_stable/bin/cache/artifacts/engine/common/flutter_patched_sdk/ --target=flutter --aot --tfa --no-print-incremental-dependencies -Dflutter.inspector.structuredErrors=true -DFLUTTER_WEB_AUTO_DETECT=true -Ddart.vm.profile=false -Ddart.vm.product=false --enable-asserts --track-widget-creation --packages /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/package_config.json --output-dill app.dill --depfile /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/flutter_build/1f083b7beecc20d87dfa8f7e4ca58986/kernel_snapshot.d package:example/main.dart
3335

36+
37+
3438
## 编译运行时dill
3539
dart run frontend_server.dart.snapshot --sdk-root /Users/lixin/Documents/flutter_macos_stable/bin/cache/artifacts/engine/common/flutter_patched_sdk/ --target=flutter --no-print-incremental-dependencies -Dflutter.inspector.structuredErrors=true -DFLUTTER_WEB_AUTO_DETECT=true -Ddart.vm.profile=false -Ddart.vm.product=false --enable-asserts --track-widget-creation --packages /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/package_config.json --output-dill app.dill --depfile /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/flutter_build/1f083b7beecc20d87dfa8f7e4ca58986/kernel_snapshot.d package:example/main.dart
3640

3741
## 测试aot编译成二进制
3842
/Users/lixin/Documents/flutter_macos_stable/bin/cache/artifacts/engine/android-arm64-release/darwin-x64/gen_snapshot --deterministic --snapshot_kind=app-aot-elf --elf=app.so --strip app.dill
3943

4044
## dill 文件注入成功检测
41-
dart /Users/lixin/Documents/FlutterWorkspace/dart_sdk/sdk/pkg/vm/bin/dump_kernel.dart app.dill injected.out.dill.txt
45+
dart run dump_kernel.dart.snapshot app.dill injected.out.dill.txt
46+
47+
dart /Users/lixin/Documents/FlutterWorkspace/dart_sdk/sdk/pkg/vm/bin/dump_kernel.dart example/.dart_tool/flutter_build/1f083b7beecc20d87dfa8f7e4ca58986/app.dill injected.out.dill.txt
4248

4349
# 替换flutter中的frontend_server.dart.snapshot
44-
将新编译的frontend_server.dart.snapshot覆盖 flutter_macos_stable/bin/cache/artifacts/engine/darwin-x64/frontend_server.dart.snapshot
50+
1.将新编译的frontend_server.dart.snapshot覆盖 flutter_macos_stable/bin/cache/artifacts/engine/darwin-x64/frontend_server.dart.snapshot
51+
52+
2.将新编译的frontend_server.dart.snapshot覆盖 /Users/lixin/Documents/flutter_macos_stable/bin/cache/dart-sdk/bin/snapshots
4553

4654
# 测试运行
4755
cd example

dump_kernel.dart.snapshot

2.58 MB
Binary file not shown.

example/lib/inject.dart

Lines changed: 158 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,45 @@ class Inject {
111111
return success;
112112
}
113113

114-
//全局catch拦截
114+
//非类中的方法拦截
115115
@pragma('vm:entry-point')
116-
@pragma("aopd:trycatch")
116+
@pragma("aopd:inject", {
117+
"importUri": "package:example/main.dart",
118+
"clsName": "DialogExt",
119+
"methodName": "-DialogExt|showNotice",
120+
"isRegex": false
121+
})
117122
//必须是static,不然不起作用
118-
static void injectTrycatch(
119-
Object exception,
120-
StackTrace? stackTrace,
121-
) async {
122-
FlutterError.dumpErrorToConsole(
123-
FlutterErrorDetails(exception: exception, stack: stackTrace),
124-
forceReport: true);
123+
static Future<bool> _injectShowNotice(
124+
Object target,
125+
String functionName,
126+
List<dynamic> positionalParams,
127+
Map<String, dynamic> namedParams,
128+
Function proceed) async {
125129
debugPrint(
126-
"[Inject] trycatch result success ${exception.runtimeType.toString()} ${stackTrace?.runtimeType.toString()}");
130+
"[Inject] $functionName start ${namedParams["title"]} ${namedParams["message"]}");
131+
bool success = await Function.apply(
132+
proceed, positionalParams, _transToNamedParams(namedParams));
133+
debugPrint("[Inject] $functionName result $success");
134+
return success;
127135
}
128136

137+
// //全局catch拦截
138+
// @pragma('vm:entry-point')
139+
// @pragma("aopd:trycatch")
140+
// //必须是static,不然不起作用
141+
// static void injectTrycatch(
142+
// String? functionName,
143+
// Object exception,
144+
// StackTrace? stackTrace,
145+
// ) async {
146+
// var info = {
147+
// "message":
148+
// "程序运行错误: $functionName | ${exception.toString()},详情: ${stackTrace?.toString()}",
149+
// };
150+
// debugPrint(info["message"].toString());
151+
// }
152+
129153
//Extension里方法拦截
130154
@pragma('vm:entry-point')
131155
@pragma("aopd:inject", {
@@ -190,6 +214,130 @@ class Inject {
190214
Function.apply(proceed, positionalParams, _transToNamedParams(namedParams));
191215
}
192216

217+
@pragma('vm:entry-point')
218+
@pragma("aopd:inject", {
219+
"importUri": "package:example/main.dart",
220+
"clsName": "MixinHomePageState2",
221+
"methodName": "-_test7",
222+
"isRegex": false
223+
})
224+
//必须是static,不然不起作用
225+
static void _injectTest7(
226+
Object target,
227+
String functionName,
228+
List<dynamic> positionalParams,
229+
Map<String, dynamic> namedParams,
230+
Function proceed) async {
231+
debugPrint(
232+
"[Inject] $functionName start ${positionalParams[0]} ${positionalParams[1]} ${namedParams["key3"]}");
233+
Function.apply(proceed, positionalParams, _transToNamedParams(namedParams));
234+
}
235+
236+
@pragma('vm:entry-point')
237+
@pragma("aopd:inject", {
238+
"importUri": "package:example/main.dart",
239+
"clsName": "RepositoryImpl",
240+
"methodName": "-getAppVersion",
241+
"isRegex": false
242+
})
243+
//必须是static,不然不起作用
244+
static Future<int> _injectGetAppVersion(
245+
Object target,
246+
String functionName,
247+
List<dynamic> positionalParams,
248+
Map<String, dynamic> namedParams,
249+
Function proceed) async {
250+
debugPrint("[Inject] $functionName start: ${namedParams["packageName"]}");
251+
int result = await Function.apply(
252+
proceed, positionalParams, _transToNamedParams(namedParams));
253+
debugPrint("[Inject] $functionName result: $result");
254+
return result;
255+
}
256+
257+
@pragma('vm:entry-point')
258+
@pragma("aopd:inject", {
259+
"importUri": "package:example/main.dart",
260+
"clsName": "BaseRepository",
261+
"methodName": "-getAppVersion2",
262+
"isRegex": false
263+
})
264+
//必须是static,不然不起作用
265+
static Future<int> _injectGetAppVersion2(
266+
Object target,
267+
String functionName,
268+
List<dynamic> positionalParams,
269+
Map<String, dynamic> namedParams,
270+
Function proceed) async {
271+
debugPrint("[Inject] $functionName start: ${namedParams["packageName"]}");
272+
int result = await Function.apply(
273+
proceed, positionalParams, _transToNamedParams(namedParams));
274+
debugPrint("[Inject] $functionName result: $result");
275+
return result;
276+
}
277+
278+
@pragma('vm:entry-point')
279+
@pragma("aopd:inject", {
280+
"importUri": "package:example/main.dart",
281+
"clsName": "RepositoryImpl",
282+
"methodName": "-getAppVersion2",
283+
"isRegex": false
284+
})
285+
//必须是static,不然不起作用
286+
static Future<int> _injectGetAppVersion22(
287+
Object target,
288+
String functionName,
289+
List<dynamic> positionalParams,
290+
Map<String, dynamic> namedParams,
291+
Function proceed) async {
292+
debugPrint(
293+
"[Inject] _injectGetAppVersion22 start: ${namedParams["packageName"]}");
294+
int result = await Function.apply(
295+
proceed, positionalParams, _transToNamedParams(namedParams));
296+
debugPrint("[Inject] _injectGetAppVersion22 result: $result");
297+
return result;
298+
}
299+
300+
@pragma('vm:entry-point')
301+
@pragma("aopd:inject", {
302+
"importUri": "package:example/test_mixin.dart",
303+
"clsName": r"_?&BaseController.*&MixinBaseController",
304+
"methodName": "-testMixin",
305+
"isRegex": true
306+
})
307+
//必须是static,不然不起作用
308+
static dynamic testMixin(
309+
Object target,
310+
String functionName,
311+
List<dynamic> positionalParams,
312+
Map<String, dynamic> namedParams,
313+
Function proceed) async {
314+
debugPrint("[Inject] testMixin start: ${namedParams["packageName"]}");
315+
316+
return Function.apply(
317+
proceed, positionalParams, _transToNamedParams(namedParams));
318+
}
319+
320+
@pragma('vm:entry-point')
321+
@pragma("aopd:inject", {
322+
"importUri": "package:example/test_mixin.dart",
323+
"clsName": "BaseControllerImpl",
324+
"methodName": "-baseTest",
325+
"isRegex": false
326+
})
327+
//必须是static,不然不起作用
328+
static dynamic baseTest(
329+
Object target,
330+
String functionName,
331+
List<dynamic> positionalParams,
332+
Map<String, dynamic> namedParams,
333+
Function proceed) async {
334+
debugPrint(
335+
"[Inject] baseTest start: ${target.runtimeType.toString()} $functionName ");
336+
337+
return Function.apply(
338+
proceed, positionalParams, _transToNamedParams(namedParams));
339+
}
340+
193341
@pragma('vm:entry-point')
194342
static Map<Symbol, dynamic> _transToNamedParams(
195343
Map<String, dynamic> namedParams) {

example/lib/main.dart

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import 'package:example/test_mixin.dart';
12
import 'package:flutter/material.dart';
23

34
//必须有,不然不起作用
5+
// ignore: unused_import
46
import 'inject.dart';
57

68
void main() {
@@ -49,7 +51,7 @@ class MyHomePage extends StatefulWidget {
4951
final String title;
5052

5153
@override
52-
State<MyHomePage> createState() => _MyHomePageState();
54+
State<MyHomePage> createState() => MyHomePageState();
5355
}
5456

5557
Future<bool> _test4(int key1, String key2, {String key3 = 'namedkey4'}) async {
@@ -64,14 +66,34 @@ Future<bool> _testtry(int key1, String key2,
6466
total++;
6567
debugPrint("$total testtry $key1 $key2 $key3");
6668
var arr = [];
67-
//print(arr[10]);
69+
debugPrint(arr[10]);
6870
} catch (exception, stackTrace) {
69-
print("${exception} ${stackTrace}");
71+
debugPrint("${exception.toString()} ${stackTrace.toString()}");
7072
}
7173
return true;
7274
}
7375

74-
extension ExtensionHomePageState on _MyHomePageState {
76+
Future<bool> _testtry2(int key1, String key2) async {
77+
return _testtry(key1, key2);
78+
}
79+
80+
abstract class GetInterface {}
81+
82+
class _GetImpl extends GetInterface {}
83+
84+
final Get = _GetImpl();
85+
86+
extension DialogExt on GetInterface {
87+
Future<bool> showNotice({
88+
String title = "提示",
89+
required String message,
90+
}) async {
91+
debugPrint(" showNotice $title $message");
92+
return true;
93+
}
94+
}
95+
96+
extension ExtensionHomePageState on MyHomePageState {
7597
Future<bool> _test5(int key1, String key2,
7698
{String key3 = 'namedkey5'}) async {
7799
total++;
@@ -87,9 +109,46 @@ mixin MixinHomePageState {
87109
}
88110
}
89111

90-
class _MyHomePageState extends State<MyHomePage> with MixinHomePageState {
112+
mixin MixinHomePageState2<T extends StatefulWidget> on State<T> {
113+
void _test7(int key1, String key2, {String key3 = 'namedkey7'}) {
114+
total++;
115+
debugPrint("$total _test7 $key1 $key2 $key3");
116+
}
117+
}
118+
119+
abstract class Repository {}
120+
121+
abstract class BaseRepository extends Repository with MixinUpgrade {
122+
Future<int> getAppVersion2({required String packageName}) async {
123+
debugPrint("getAppVersion2 $packageName");
124+
return 0;
125+
}
126+
}
127+
128+
mixin MixinUpgrade on Repository {
129+
Future<int> getAppVersion({required String packageName});
130+
}
131+
132+
class RepositoryImpl extends BaseRepository {
133+
@override
134+
Future<int> getAppVersion({required String packageName}) async {
135+
debugPrint("getAppVersion $packageName");
136+
return 0;
137+
}
138+
139+
@override
140+
Future<int> getAppVersion2({required String packageName}) async {
141+
debugPrint("getAppVersion2 override $packageName");
142+
return super.getAppVersion2(packageName: packageName);
143+
}
144+
}
145+
146+
class MyHomePageState extends State<MyHomePage>
147+
with MixinHomePageState, MixinHomePageState2 {
91148
int _counter = 0;
92149

150+
final BaseRepository repository = RepositoryImpl();
151+
93152
void _test1(int key1, String key2, {String key3 = 'namedkey1'}) {
94153
total++;
95154
debugPrint("$total _test1 $key1 $key2 $key3");
@@ -109,15 +168,21 @@ class _MyHomePageState extends State<MyHomePage> with MixinHomePageState {
109168
return true;
110169
}
111170

112-
void _incrementCounter() {
171+
void _incrementCounter() async {
113172
total = 0;
114-
_test1(_counter, "positional1");
115-
_test2(_counter, "positional2");
116-
_test3(_counter, "positional3");
117-
_test4(_counter, "positional4");
118-
_test5(_counter, "positional5");
119-
_test6(_counter, "positional6");
120-
_testtry(_counter, "positional7");
173+
// _test1(_counter, "positional1");
174+
// _test2(_counter, "positional2");
175+
// _test3(_counter, "positional3");
176+
// await _test4(_counter, "positional4");
177+
// await _test5(_counter, "positional5");
178+
// _test6(_counter, "positional6");
179+
_test7(_counter, "positional7");
180+
// await repository.getAppVersion(packageName: "packageName");
181+
// await repository.getAppVersion2(packageName: "packageName2");
182+
//await Get.showNotice(message: "this is a notice");
183+
//_testtry2(_counter, "positional7");
184+
BaseControllerImpl baseControllerImpl = BaseControllerImpl();
185+
baseControllerImpl.baseTest();
121186
setState(() {
122187
// This call to setState tells the Flutter framework that something has
123188
// changed in this State, which causes it to rerun the build method below

example/lib/test_mixin.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:flutter/foundation.dart';
2+
3+
class BaseController {}
4+
5+
mixin MixinBaseController on BaseController {
6+
void testMixin() {
7+
debugPrint("testMixin");
8+
}
9+
}
10+
11+
class BaseControllerImpl extends BaseController with MixinBaseController {
12+
void baseTest() {
13+
debugPrint("baseTest");
14+
testMixin();
15+
}
16+
}

frontend_server.dart.snapshot

1.48 KB
Binary file not shown.

0 commit comments

Comments
 (0)