Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 29b896f

Browse files
committed
Implemented library uri support for FlutterFragments and FlutterActivities.
1 parent 154bd96 commit 29b896f

File tree

9 files changed

+78
-11
lines changed

9 files changed

+78
-11
lines changed

shell/platform/android/io/flutter/embedding/android/FlutterActivity.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package io.flutter.embedding.android;
66

77
import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DART_ENTRYPOINT_META_DATA_KEY;
8+
import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DART_ENTRYPOINT_URI_META_DATA_KEY;
89
import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DEFAULT_BACKGROUND_MODE;
910
import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DEFAULT_DART_ENTRYPOINT;
1011
import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DEFAULT_INITIAL_ROUTE;
@@ -824,6 +825,18 @@ public String getDartEntrypointFunctionName() {
824825
}
825826
}
826827

828+
@Nullable
829+
public String getDartEntrypointLibraryUri() {
830+
try {
831+
Bundle metaData = getMetaData();
832+
String desiredDartLibraryUri =
833+
metaData != null ? metaData.getString(DART_ENTRYPOINT_URI_META_DATA_KEY) : null;
834+
return desiredDartLibraryUri;
835+
} catch (PackageManager.NameNotFoundException e) {
836+
return null;
837+
}
838+
}
839+
827840
/**
828841
* The initial route that a Flutter app will render upon loading and executing its Dart code.
829842
*

shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,16 @@ private void doInitialFlutterViewRun() {
417417
initialRoute = DEFAULT_INITIAL_ROUTE;
418418
}
419419
}
420+
@Nullable String libraryUri = host.getDartEntrypointLibraryUri();
420421
Log.v(
421422
TAG,
422423
"Executing Dart entrypoint: "
423-
+ host.getDartEntrypointFunctionName()
424-
+ ", and sending initial route: "
425-
+ initialRoute);
424+
+ host.getDartEntrypointFunctionName()
425+
+ ", library uri: "
426+
+ libraryUri
427+
== null
428+
? "\"\""
429+
: libraryUri + ", and sending initial route: " + initialRoute);
426430

427431
// The engine needs to receive the Flutter app's initial route before executing any
428432
// Dart code to ensure that the initial route arrives in time to be applied.
@@ -435,8 +439,11 @@ private void doInitialFlutterViewRun() {
435439

436440
// Configure the Dart entrypoint and execute it.
437441
DartExecutor.DartEntrypoint entrypoint =
438-
new DartExecutor.DartEntrypoint(
439-
appBundlePathOverride, host.getDartEntrypointFunctionName());
442+
libraryUri == null
443+
? new DartExecutor.DartEntrypoint(
444+
appBundlePathOverride, host.getDartEntrypointFunctionName())
445+
: new DartExecutor.DartEntrypoint(
446+
appBundlePathOverride, libraryUri, host.getDartEntrypointFunctionName());
440447
flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint);
441448
}
442449

@@ -916,6 +923,14 @@ private void ensureAlive() {
916923
@NonNull
917924
String getDartEntrypointFunctionName();
918925

926+
/**
927+
* Returns the URI of the Dart library which contains the entrypoint method (example
928+
* "package:foo_package/main.dart"). If null, this will default to the same library as the
929+
* `main()` function in the Dart program.
930+
*/
931+
@Nullable
932+
String getDartEntrypointLibraryUri();
933+
919934
/** Returns the path to the app bundle where the Dart code exists. */
920935
@NonNull
921936
String getAppBundlePath();

shell/platform/android/io/flutter/embedding/android/FlutterActivityLaunchConfigs.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
public class FlutterActivityLaunchConfigs {
1212
// Meta-data arguments, processed from manifest XML.
1313
/* package */ static final String DART_ENTRYPOINT_META_DATA_KEY = "io.flutter.Entrypoint";
14+
/* package */ static final String DART_ENTRYPOINT_URI_META_DATA_KEY = "io.flutter.EntrypointUri";
1415
/* package */ static final String INITIAL_ROUTE_META_DATA_KEY = "io.flutter.InitialRoute";
1516
/* package */ static final String SPLASH_SCREEN_META_DATA_KEY =
1617
"io.flutter.embedding.android.SplashScreenDrawable";

shell/platform/android/io/flutter/embedding/android/FlutterFragment.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ public class FlutterFragment extends Fragment
105105

106106
/** The Dart entrypoint method name that is executed upon initialization. */
107107
protected static final String ARG_DART_ENTRYPOINT = "dart_entrypoint";
108+
/** */
109+
protected static final String ARG_DART_ENTRYPOINT_URI = "dart_entrypoint_uri";
108110
/** Initial Flutter route that is rendered in a Navigator widget. */
109111
protected static final String ARG_INITIAL_ROUTE = "initial_route";
110112
/** Whether the activity delegate should handle the deeplinking request. */
@@ -1026,6 +1028,12 @@ public String getDartEntrypointFunctionName() {
10261028
return getArguments().getString(ARG_DART_ENTRYPOINT, "main");
10271029
}
10281030

1031+
@Override
1032+
@Nullable
1033+
public String getDartEntrypointLibraryUri() {
1034+
return getArguments().getString(ARG_DART_ENTRYPOINT_URI);
1035+
}
1036+
10291037
/**
10301038
* A custom path to the bundle that contains this Flutter app's resources, e.g., Dart code
10311039
* snapshots.

shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,25 @@ public void itExecutesDartEntrypointProvidedByHost() {
320320
verify(mockFlutterEngine.getDartExecutor(), times(1)).executeDartEntrypoint(eq(dartEntrypoint));
321321
}
322322

323+
@Test
324+
public void itExecutesDartLibraryUriProvidedByHost() {
325+
when(mockHost.getAppBundlePath()).thenReturn("/my/bundle/path");
326+
when(mockHost.getDartEntrypointFunctionName()).thenReturn("myEntrypoint");
327+
when(mockHost.getDartEntrypointLibraryUri()).thenReturn("package:foo/bar.dart");
328+
329+
DartExecutor.DartEntrypoint expectedEntrypoint =
330+
new DartExecutor.DartEntrypoint("/my/bundle/path", "package:foo/bar.dart", "myEntrypoint");
331+
332+
FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost);
333+
334+
delegate.onAttach(RuntimeEnvironment.application);
335+
delegate.onCreateView(null, null, null, 0, true);
336+
delegate.onStart();
337+
338+
verify(mockFlutterEngine.getDartExecutor(), times(1))
339+
.executeDartEntrypoint(eq(expectedEntrypoint));
340+
}
341+
323342
@Test
324343
public void itUsesDefaultFlutterLoaderAppBundlePathWhenUnspecified() {
325344
// ---- Test setup ----

shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public void itCreatesDefaultIntentWithExpectedDefaults() {
9595
flutterActivity.setDelegate(new FlutterActivityAndFragmentDelegate(flutterActivity));
9696

9797
assertEquals("main", flutterActivity.getDartEntrypointFunctionName());
98+
assertNull(flutterActivity.getDartEntrypointLibraryUri());
9899
assertEquals("/", flutterActivity.getInitialRoute());
99100
assertArrayEquals(new String[] {}, flutterActivity.getFlutterShellArgs().toArray());
100101
assertTrue(flutterActivity.shouldAttachEngineToActivity());

shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@ public String getDartEntrypointFunctionName() {
305305
return "main";
306306
}
307307

308+
@Nullable
309+
@Override
310+
public String getDartEntrypointLibraryUri() {
311+
return null;
312+
}
313+
308314
@NonNull
309315
@Override
310316
public String getAppBundlePath() {

shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public void itCreatesDefaultFragmentWithExpectedDefaults() {
3838
fragment.setDelegate(new FlutterActivityAndFragmentDelegate(fragment));
3939

4040
assertEquals("main", fragment.getDartEntrypointFunctionName());
41+
assertNull(fragment.getDartEntrypointLibraryUri());
4142
assertEquals("/", fragment.getInitialRoute());
4243
assertArrayEquals(new String[] {}, fragment.getFlutterShellArgs().toArray());
4344
assertTrue(fragment.shouldAttachEngineToActivity());

shell/platform/darwin/ios/framework/Headers/FlutterEngine.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ FLUTTER_DARWIN_EXPORT
219219
* FlutterDefaultDartEntrypoint (or nil); this will default to `main()`. If it is not the app's
220220
* main() function, that function must be decorated with `@pragma(vm:entry-point)` to ensure the
221221
* method is not tree-shaken by the Dart compiler.
222-
* @param uri The URI of the Dart library which contains the entrypoint method. IF nil,
223-
* this will default to the same library as the `main()` function in the Dart program.
222+
* @param uri The URI of the Dart library which contains the entrypoint method
223+
* (example "package:foo_package/main.dart"). If nil, this will default to
224+
* the same library as the `main()` function in the Dart program.
224225
* @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise.
225226
*/
226227
- (BOOL)runWithEntrypoint:(nullable NSString*)entrypoint libraryURI:(nullable NSString*)uri;
@@ -236,8 +237,9 @@ FLUTTER_DARWIN_EXPORT
236237
* FlutterDefaultDartEntrypoint (or nil); this will default to `main()`. If it is not the app's
237238
* main() function, that function must be decorated with `@pragma(vm:entry-point)` to ensure the
238239
* method is not tree-shaken by the Dart compiler.
239-
* @param libraryURI The URI of the Dart library which contains the entrypoint method. IF nil,
240-
* this will default to the same library as the `main()` function in the Dart program.
240+
* @param libraryURI The URI of the Dart library which contains the entrypoint
241+
* method (example "package:foo_package/main.dart"). If nil, this will
242+
* default to the same library as the `main()` function in the Dart program.
241243
* @param initialRoute The name of the initial Flutter `Navigator` `Route` to load. If this is
242244
* FlutterDefaultInitialRoute (or nil), it will default to the "/" route.
243245
* @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise.
@@ -257,8 +259,9 @@ FLUTTER_DARWIN_EXPORT
257259
* FlutterDefaultDartEntrypoint (or nil); this will default to `main()`. If it is not the app's
258260
* main() function, that function must be decorated with `@pragma(vm:entry-point)` to ensure the
259261
* method is not tree-shaken by the Dart compiler.
260-
* @param libraryURI The URI of the Dart library which contains the entrypoint method. IF nil,
261-
* this will default to the same library as the `main()` function in the Dart program.
262+
* @param libraryURI The URI of the Dart library which contains the entrypoint
263+
* method (example "package:foo_package/main.dart"). If nil, this will
264+
* default to the same library as the `main()` function in the Dart program.
262265
* @param initialRoute The name of the initial Flutter `Navigator` `Route` to load. If this is
263266
* FlutterDefaultInitialRoute (or nil), it will default to the "/" route.
264267
* @param entrypointArgs Arguments passed as a list of string to Dart's entrypoint function.

0 commit comments

Comments
 (0)