-
Notifications
You must be signed in to change notification settings - Fork 6k
Make FlutterEngineGroup support dart entrypoint args #29096
Make FlutterEngineGroup support dart entrypoint args #29096
Conversation
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
97c7562
to
8a29f14
Compare
(Remove "need tests" label because unit tests has been added) |
Why can't you use platform channels for this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The underlying issue warrants further discussion of the use-case and alternatives (in a design doc perhaps) before jumping into an implementation. This data blob is persistent across the lifecycle of the engine and cannot be reclaimed. It has the possibility of growing as the application grows more complex.
e684b21
to
e893583
Compare
834be03
to
58bb313
Compare
lib/ui/platform_dispatcher.dart
Outdated
dynamic getInitialArguments({required List<String> rawArgs}) { | ||
if (rawArgs.isEmpty) return null; | ||
return json.decode(rawArgs[0]); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should avoid using dynamic
, and avoid using or assuming this is JSON.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 We should avoid using dynamic
Done. Using Object?
now
2 and avoid using or assuming this is JSON.
Done.
The current solution cannot avoid using json, but some changes can be made here.
We can change the dart entrypoint args passed by the platform into the following format
['--initial-arguments','{\"foo\":\"bar\"}']
Then we change the code to the following
Object? getInitialArguments({required List<String> rawArgs}) {
if (rawArgs.isEmpty) return null;
final int initialArgumentsIndex = rawArgs.indexOf('--initial-arguments') + 1;
if (initialArgumentsIndex <= 0 || initialArgumentsIndex == rawArgs.length) return null;
return json.decode(rawArgs[initialArgumentsIndex]);
}
void canRecieveEmptyArguments(List<String> args) { | ||
final dynamic initialArguments = PlatformDispatcher.instance.getInitialArguments(rawArgs: args); | ||
notifyNativeWhenEngineRun(args.isEmpty && initialArguments == null); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: newline at EOF
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One high level concern: the args get stuck in memory forever even with this patch.
If we do this for debug to support restart it's probably acceptable, but we should not be doing this for profile/release where restart isn't possible.
I have considered this problem, and currently I have two solutions:
Hi, @dnfield , do you think these two options are feasible? If feasible, which one do you prefer? |
I'd say just guard it with conditional compilation, but probably on |
Ok, I'll do that :) |
b1a8771
to
2962099
Compare
* must be decorated with `@pragma(vm:entry-point)` to ensure themethod is not tree-shaken by the | ||
* Dart compiler. | ||
*/ | ||
@property(nonatomic, copy) NSString* entrypoint; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These properties are nullable right? You should specify that @property(nonatomic, copy, nullable)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
…s::dart_entrypoint_args both be set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I read through everything again. This looks close. The only important thing I noticed is that one test that I think should make sure the arguments match on the ui thread with the ones that were supplied.
private Context context; | ||
private DartEntrypoint dartEntrypoint; | ||
private String initialRoute; | ||
private List<String> dartEntrypointArgs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nullable annotations would be helpful here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
private native void nativeRunBundleAndSnapshotFromLibrary( | ||
long nativeShellHolderId, | ||
@NonNull String bundlePath, | ||
@Nullable String entrypointFunctionName, | ||
@Nullable String pathToEntrypointFunction, | ||
@NonNull AssetManager manager); | ||
@NonNull AssetManager manager, | ||
@NonNull List<String> entrypointArgs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be nullable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -42,16 +54,32 @@ - (FlutterEngine*)makeEngineWithEntrypoint:(nullable NSString*)entrypoint | |||
- (FlutterEngine*)makeEngineWithEntrypoint:(nullable NSString*)entrypoint | |||
libraryURI:(nullable NSString*)libraryURI | |||
initialRoute:(nullable NSString*)initialRoute { | |||
NSString* engineName = [NSString stringWithFormat:@"%@.%d", self.name, ++_enginesCreatedCount]; | |||
FlutterEngineGroupOptions* options = [FlutterEngineGroupOptions new]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are new analyzer rules coming, r/[FlutterEngineGroupOptions new]/[[FlutterEngineGroupOptions alloc] init]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a TODO on settings.h to remove the duplicated entry, and link it to the existing issue that has context.
This LGTM once it LGT @gaaclarke
Chinmay says his concerns have been addressed
Done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks @ColdPaleLight =)
This PR try to add a new parameter named initialArguments to pass the startup arguments from platform to Flutter app
fixes: flutter/flutter#91547 flutter/flutter#23786 flutter/flutter#34170
design doc: https://docs.google.com/document/d/1ufsbXdhCm1qTAY2eXsRrVrfxED5WCZgqQ-Tm2LzScoE/edit
sample: https://github.com/ColdPaleLight/multiple_flutters/
Pre-launch Checklist
writing and running engine tests.
///
).