59 private static final String SPLASH_SCREEN_META_DATA_KEY =
60 "io.flutter.app.android.SplashScreenUntilFirstFrame";
61 private static final String TAG =
"FlutterActivityDelegate";
62 private static final LayoutParams matchParent =
63 new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
92 private final Activity activity;
95 private View launchView;
98 this.activity = Preconditions.checkNotNull(activity);
99 this.viewFactory = Preconditions.checkNotNull(viewFactory);
110 return flutterView.getPluginRegistry().hasPlugin(
key);
114 @SuppressWarnings(
"unchecked")
116 return (
T) flutterView.getPluginRegistry().valuePublishedByPlugin(pluginKey);
121 return flutterView.getPluginRegistry().registrarFor(pluginKey);
126 int requestCode, String[] permissions,
int[] grantResults) {
129 .onRequestPermissionsResult(requestCode, permissions, grantResults);
134 return flutterView.getPluginRegistry().onActivityResult(requestCode, resultCode, data);
140 window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
141 window.setStatusBarColor(0x40000000);
142 window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
144 String[]
args = getArgsFromIntent(activity.getIntent());
145 FlutterMain.ensureInitializationComplete(activity.getApplicationContext(),
args);
148 if (flutterView ==
null) {
150 flutterView =
new FlutterView(activity,
null, nativeView);
151 flutterView.setLayoutParams(matchParent);
152 activity.setContentView(flutterView);
153 launchView = createLaunchView();
154 if (launchView !=
null) {
159 if (loadIntent(activity.getIntent())) {
163 String appBundlePath = FlutterMain.findAppBundlePath();
164 if (appBundlePath !=
null) {
165 runBundle(appBundlePath);
173 if (!isDebuggable() || !loadIntent(intent)) {
174 flutterView.getPluginRegistry().onNewIntent(intent);
178 private boolean isDebuggable() {
179 return (activity.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
184 Application app = (Application) activity.getApplicationContext();
191 if (flutterView !=
null) {
192 flutterView.onPause();
198 if (flutterView !=
null) {
199 flutterView.onStart();
205 Application app = (Application) activity.getApplicationContext();
214 flutterView.onStop();
219 if (flutterView !=
null) {
220 flutterView.onPostResume();
226 Application app = (Application) activity.getApplicationContext();
233 if (flutterView !=
null) {
234 final boolean detach =
235 flutterView.getPluginRegistry().onViewDestroy(flutterView.getFlutterNativeView());
239 flutterView.detach();
241 flutterView.destroy();
248 if (flutterView !=
null) {
249 flutterView.popRoute();
257 flutterView.getPluginRegistry().onUserLeaveHint();
262 flutterView.getPluginRegistry().onWindowFocusChanged(hasFocus);
269 if (level == TRIM_MEMORY_RUNNING_LOW) {
270 flutterView.onMemoryPressure();
276 flutterView.onMemoryPressure();
282 private static String[] getArgsFromIntent(Intent intent) {
286 ArrayList<String>
args =
new ArrayList<>();
287 if (intent.getBooleanExtra(
"trace-startup",
false)) {
288 args.add(
"--trace-startup");
290 if (intent.getBooleanExtra(
"start-paused",
false)) {
291 args.add(
"--start-paused");
293 if (intent.getBooleanExtra(
"disable-service-auth-codes",
false)) {
294 args.add(
"--disable-service-auth-codes");
296 if (intent.getBooleanExtra(
"use-test-fonts",
false)) {
297 args.add(
"--use-test-fonts");
299 if (intent.getBooleanExtra(
"enable-dart-profiling",
false)) {
300 args.add(
"--enable-dart-profiling");
302 if (intent.getBooleanExtra(
"enable-software-rendering",
false)) {
303 args.add(
"--enable-software-rendering");
305 if (intent.getBooleanExtra(
"skia-deterministic-rendering",
false)) {
306 args.add(
"--skia-deterministic-rendering");
308 if (intent.getBooleanExtra(
"trace-skia",
false)) {
309 args.add(
"--trace-skia");
311 if (intent.getBooleanExtra(
"trace-systrace",
false)) {
312 args.add(
"--trace-systrace");
314 if (intent.hasExtra(
"trace-to-file")) {
315 args.add(
"--trace-to-file=" + intent.getStringExtra(
"trace-to-file"));
317 if (intent.getBooleanExtra(
"dump-skp-on-shader-compilation",
false)) {
318 args.add(
"--dump-skp-on-shader-compilation");
320 if (intent.getBooleanExtra(
"cache-sksl",
false)) {
321 args.add(
"--cache-sksl");
323 if (intent.getBooleanExtra(
"purge-persistent-cache",
false)) {
324 args.add(
"--purge-persistent-cache");
326 if (intent.getBooleanExtra(
"verbose-logging",
false)) {
327 args.add(
"--verbose-logging");
329 int vmServicePort = intent.getIntExtra(
"vm-service-port", 0);
330 if (vmServicePort > 0) {
331 args.add(
"--vm-service-port=" + Integer.toString(vmServicePort));
335 vmServicePort = intent.getIntExtra(
"observatory-port", 0);
336 if (vmServicePort > 0) {
337 args.add(
"--vm-service-port=" + Integer.toString(vmServicePort));
340 if (intent.getBooleanExtra(
"endless-trace-buffer",
false)) {
341 args.add(
"--endless-trace-buffer");
346 if (intent.hasExtra(
"dart-flags")) {
347 args.add(
"--dart-flags=" + intent.getStringExtra(
"dart-flags"));
349 if (!
args.isEmpty()) {
350 String[] argsArray =
new String[
args.size()];
351 return args.toArray(argsArray);
356 private boolean loadIntent(Intent intent) {
357 String
action = intent.getAction();
358 if (Intent.ACTION_RUN.equals(
action)) {
359 String
route = intent.getStringExtra(
"route");
360 String appBundlePath = intent.getDataString();
361 if (appBundlePath ==
null) {
363 appBundlePath = FlutterMain.findAppBundlePath();
366 flutterView.setInitialRoute(route);
369 runBundle(appBundlePath);
376 private void runBundle(String appBundlePath) {
377 if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
378 FlutterRunArguments
args =
new FlutterRunArguments();
379 args.bundlePath = appBundlePath;
380 args.entrypoint =
"main";
381 flutterView.runFromBundle(
args);
391 private View createLaunchView() {
392 if (!showSplashScreenUntilFirstFrame()) {
395 final Drawable launchScreenDrawable = getLaunchScreenDrawableFromActivityTheme();
396 if (launchScreenDrawable ==
null) {
399 final View view =
new View(activity);
400 view.setLayoutParams(matchParent);
401 view.setBackground(launchScreenDrawable);
414 @SuppressWarnings(
"deprecation")
415 private Drawable getLaunchScreenDrawableFromActivityTheme() {
416 TypedValue typedValue =
new TypedValue();
417 if (!activity.getTheme().resolveAttribute(
android.R.attr.windowBackground, typedValue,
true)) {
420 if (typedValue.resourceId == 0) {
424 return activity.getResources().getDrawable(typedValue.resourceId);
425 }
catch (NotFoundException e) {
426 Log.e(TAG,
"Referenced launch screen windowBackground resource does not exist");
435 private Boolean showSplashScreenUntilFirstFrame() {
437 ActivityInfo activityInfo =
440 .getActivityInfo(activity.getComponentName(), PackageManager.GET_META_DATA);
441 Bundle metadata = activityInfo.metaData;
442 return metadata !=
null && metadata.getBoolean(SPLASH_SCREEN_META_DATA_KEY);
443 }
catch (NameNotFoundException e) {
457 private void addLaunchView() {
458 if (launchView ==
null) {
462 activity.addContentView(launchView, matchParent);
463 flutterView.addFirstFrameListener(
466 public void onFirstFrame() {
467 FlutterActivityDelegate.this
473 new AnimatorListenerAdapter() {
475 public void onAnimationEnd(Animator animation) {
478 ((ViewGroup) FlutterActivityDelegate.this.launchView.getParent())
479 .removeView(FlutterActivityDelegate.this.launchView);
480 FlutterActivityDelegate.this.launchView = null;
484 FlutterActivityDelegate.this.flutterView.removeFirstFrameListener(this);
493 activity.setTheme(
android.R.style.Theme_Black_NoTitleBar);