Android ActivityControlSurface attachToActivity signature change

Summary

#

A new ActivityControlSurface method:

java
void attachToActivity(
    @NonNull ExclusiveAppComponent<Activity> exclusiveActivity,
    @NonNull Lifecycle lifecycle);

is replacing the now deprecated method:

java
void attachToActivity(@NonNull Activity activity, @NonNull Lifecycle lifecycle);

The existing deprecated method with the Activity parameter was removed in Flutter 2.

Context

#

In order for custom Activities to also supply the Activity lifecycle events Flutter plugins expect using the ActivityAware interface, the FlutterEngine exposed a getActivityControlSurface() API.

This allows custom Activities to signal to the engine (with which it has a (0|1):1 relationship) that it was being attached or detached from the engine.

However, the previous API had the flaw that it didn't enforce exclusion between activities connecting to the engine, thus enabling n:1 relationships between the activity and the engine, causing lifecycle cross-talk issues.

Description of change

#

After Issue #21272, instead of attaching your activity to the FlutterEngine by using the:

java
void attachToActivity(@NonNull Activity activity, @NonNull Lifecycle lifecycle);

API, which is now deprecated, instead use:

java
void attachToActivity(
    @NonNull ExclusiveAppComponent<Activity> exclusiveActivity,
    @NonNull Lifecycle lifecycle);

An ExclusiveAppComponent<Activity> interface is now expected instead of an Activity. The ExclusiveAppComponent<Activity> provides a callback in case your exclusive activity is being replaced by another activity attaching itself to the FlutterEngine.

java
void detachFromActivity();

API remains unchanged and you're still expected to call it when your custom activity is being destroyed naturally.

Migration guide

#

If you have your own activity holding a FlutterView, replace calls to:

java
void attachToActivity(@NonNull Activity activity, @NonNull Lifecycle lifecycle);

with calls to:

java
void attachToActivity(
    @NonNull ExclusiveAppComponent<Activity> exclusiveActivity,
    @NonNull Lifecycle lifecycle);

on the ActivityControlSurface that you obtained by calling getActivityControlSurface() on the FlutterEngine.

Wrap your activity with an ExclusiveAppComponent<Activity> and implement the callback method:

java
void detachFromFlutterEngine();

to handle your activity being replaced by another activity being attached to the FlutterEngine. Generally, you want to perform the same detaching operations as performed when the activity is being naturally destroyed.

Timeline

#

Landed in version: 1.23.0-7.0.pre
In stable release: 2.0.0

References

#

Motivating bug: Issue #66192—Non exclusive UI components attached to the FlutterEngine causes event crosstalk