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

Commit 1da33b5

Browse files
committed
comments
1 parent 3785fae commit 1da33b5

4 files changed

Lines changed: 52 additions & 34 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
* <li>Chooses Flutter's initial route.
6565
* <li>Renders {@code Activity} transparently, if desired.
6666
* <li>Offers hooks for subclasses to provide and configure a {@link FlutterEngine}.
67+
<li>Save and restore instance state, see {@code shouldRestoreAndSaveState()};
6768
* </ul>
6869
*
6970
* <p><strong>Dart entrypoint, initial route, and app bundle path</strong>
@@ -956,6 +957,7 @@ public boolean shouldRestoreAndSaveState() {
956957
return getIntent().getBooleanExtra(EXTRA_ENABLE_STATE_RESTORATION, false);
957958
}
958959
if (getCachedEngineId() != null) {
960+
// Prevent overwriting the existing state in a cached engine with restoration state.
959961
return false;
960962
}
961963
return true;

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,19 +299,19 @@ void onActivityCreated(@Nullable Bundle bundle) {
299299
Log.v(TAG, "onActivityCreated. Giving framework and plugins an opportunity to restore state.");
300300
ensureAlive();
301301

302-
Bundle pluginsBundle = null;
303-
byte[] frameworkBundle = null;
302+
Bundle pluginState = null;
303+
byte[] frameworkState = null;
304304
if (bundle != null) {
305-
pluginsBundle = bundle.getBundle(PLUGINS_RESTORATION_BUNDLE_KEY);
306-
frameworkBundle = bundle.getByteArray(FRAMEWORK_RESTORATION_BUNDLE_KEY);
305+
pluginState = bundle.getBundle(PLUGINS_RESTORATION_BUNDLE_KEY);
306+
frameworkState = bundle.getByteArray(FRAMEWORK_RESTORATION_BUNDLE_KEY);
307307
}
308308

309309
if (host.shouldRestoreAndSaveState()) {
310-
flutterEngine.getRestorationChannel().setRestorationData(frameworkBundle);
310+
flutterEngine.getRestorationChannel().setRestorationData(frameworkState);
311311
}
312312

313313
if (host.shouldAttachEngineToActivity()) {
314-
flutterEngine.getActivityControlSurface().onRestoreInstanceState(pluginsBundle);
314+
flutterEngine.getActivityControlSurface().onRestoreInstanceState(pluginState);
315315
}
316316
}
317317

shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -166,26 +166,33 @@ public FlutterEngine(
166166
* Same as {@link #FlutterEngine(Context, String[], boolean)} with added support for configuring
167167
* whether the engine will receive restoration data.
168168
*
169-
* <p>When the engine is configured to receive restoration data {@code
170-
* RestorationChannel.setRestorationData(byte[] data)} must be called to provide the restoration
171-
* data. All requests to get restoration data from the framework will be blocked until that method
172-
* is called. If the engine is configured to wait for restoration data, but it turns out later
173-
* that no restoration data has been provided by the operating system, that method must still be
174-
* called with null as an argument to indicate "no data".
169+
* <p>The {@code waitForRestorationData} flag controls whether the engine delays responding to
170+
* requests from the framework for restoration data until that data has been provided to the
171+
* engine via {@code RestorationChannel.setRestorationData(byte[] data)}. If the flag is false,
172+
* the framework may temporarily initialize itself to default values before the restoration data
173+
* has been made available to the engine. Setting {@code waitForRestorationData} to true avoids
174+
* this extra work by delaying initialization until the data is available.
175+
*
176+
* <p>When {@code waitForRestorationData} is set, {@code
177+
* RestorationChannel.setRestorationData(byte[] data)} must be called at a later point in time.
178+
* If it later turns out that no restoration data is available to restore the framework from,
179+
* that method must still be called with null as an argument to indicate "no data".
180+
*
181+
* <p>If the framework never requests the restoration data, this flag has no effect.
175182
*/
176183
public FlutterEngine(
177184
@NonNull Context context,
178185
@Nullable String[] dartVmArgs,
179186
boolean automaticallyRegisterPlugins,
180-
boolean willProvideRestorationData) {
187+
boolean waitForRestorationData) {
181188
this(
182189
context,
183190
FlutterLoader.getInstance(),
184191
new FlutterJNI(),
185192
new PlatformViewsController(),
186193
dartVmArgs,
187194
automaticallyRegisterPlugins,
188-
willProvideRestorationData);
195+
waitForRestorationData);
189196
}
190197

191198
/**
@@ -252,7 +259,7 @@ public FlutterEngine(
252259
@NonNull PlatformViewsController platformViewsController,
253260
@Nullable String[] dartVmArgs,
254261
boolean automaticallyRegisterPlugins,
255-
boolean willProvideRestorationData) {
262+
boolean waitForRestorationData) {
256263
this.flutterJNI = flutterJNI;
257264
flutterLoader.startInitialization(context.getApplicationContext());
258265
flutterLoader.ensureInitializationComplete(context, dartVmArgs);
@@ -275,7 +282,7 @@ public FlutterEngine(
275282
mouseCursorChannel = new MouseCursorChannel(dartExecutor);
276283
navigationChannel = new NavigationChannel(dartExecutor);
277284
platformChannel = new PlatformChannel(dartExecutor);
278-
restorationChannel = new RestorationChannel(dartExecutor, willProvideRestorationData);
285+
restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);
279286
settingsChannel = new SettingsChannel(dartExecutor);
280287
systemChannel = new SystemChannel(dartExecutor);
281288
textInputChannel = new TextInputChannel(dartExecutor);

shell/platform/android/io/flutter/embedding/engine/systemchannels/RestorationChannel.java

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
*
2121
* <p>The channel can be configured to delay responding to the framework's request for restoration
2222
* data via {@code waitForRestorationData} until the engine-side has provided the data. This is
23-
* useful for use cases where the engine is pre-warmed at a point in the application's life cycle
24-
* where the operating system has not been made available to the engine yet. For example, if the
25-
* engine is pre-warmed as part of the Application before an Activity is created, this flag should
26-
* be set to true because Android will only provide the restoration data to the Activity.
23+
* useful when the engine is pre-warmed at a point in the application's life cycle where the
24+
* restoration data is not available yet. For example, if the engine is pre-warmed as part of the
25+
* Application before an Activity is created, this flag should be set to true because Android will
26+
* only provide the restoration data to the Activity during the onCreate callback.
2727
*
2828
* <p>The current restoration data provided by the framework can be read via {@code
2929
* getRestorationData()}.
@@ -46,20 +46,26 @@ public RestorationChannel(
4646
}
4747

4848
/**
49-
* Whether {@code setRestorationData} will be called to provide restoration data for the
50-
* framework.
49+
* Whether the channel delays responding to the framework's initial request for restoration data
50+
* until {@code setRestorationData} has been called.
5151
*
52-
* <p>When this is set to true, the channel will delay answering any requests for restoration data
53-
* by the framework until {@code setRestorationData} has been called. It must be set to false if
54-
* the engine never calls {@code setRestorationData}. If it has been set to true, but it later
55-
* turns out that there is no restoration data, {@code setRestorationData} must be called with
56-
* null.
52+
* <p>If the engine never calls {@code setRestorationData} this flag must be set to false.
53+
* If set to true, the engine must call {@code setRestorationData} either with the actual
54+
* restoration data as argument or null if it turns out that there is no restoration data.
55+
*
56+
* <p>If the response to the framework's request for restoration data is not delayed until the
57+
* data has been set via {@code setRestorationData}, the framework may intermittently initialize
58+
* itself to default values until the restoration data has been made available. Setting this flag
59+
* to true avoids that extra work.
5760
*/
5861
public final boolean waitForRestorationData;
5962

60-
private MethodChannel channel;
63+
// Holds the the most current restoration data which may have been provided by the engine
64+
// via "setRestorationData" or by the framework via the method channel. This is the data the
65+
// framework should be restored to in case the app is terminated.
6166
private byte[] restorationData;
62-
private MethodChannel.Result pendingResult;
67+
private MethodChannel channel;
68+
private MethodChannel.Result pendingFrameworkRequest;
6369
private boolean engineHasProvidedData = false;
6470
private boolean frameworkHasRequestedData = false;
6571

@@ -71,11 +77,14 @@ public byte[] getRestorationData() {
7177
/** Set the restoration data from which the framework will restore its state. */
7278
public void setRestorationData(byte[] data) {
7379
engineHasProvidedData = true;
74-
if (pendingResult != null) {
75-
pendingResult.success(data);
76-
pendingResult = null;
80+
if (pendingFrameworkRequest != null) {
81+
// If their is a pending request from the framework, answer it.
82+
pendingFrameworkRequest.success(data);
83+
pendingFrameworkRequest = null;
7784
restorationData = data;
7885
} else if (frameworkHasRequestedData) {
86+
// If the framework has previously received the engine's restoration data, push the new data
87+
// directly to it.
7988
channel.invokeMethod(
8089
"push",
8190
data,
@@ -101,6 +110,7 @@ public void notImplemented() {
101110
}
102111
});
103112
} else {
113+
// Otherwise, just cache the data until the framework asks for it.
104114
restorationData = data;
105115
}
106116
}
@@ -121,7 +131,6 @@ public void clearData() {
121131
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
122132
final String method = call.method;
123133
final Object args = call.arguments;
124-
Log.v(TAG, "Received '" + method + "' message.");
125134
switch (method) {
126135
case "put":
127136
restorationData = (byte[]) args;
@@ -132,7 +141,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
132141
if (engineHasProvidedData || !waitForRestorationData) {
133142
result.success(restorationData);
134143
} else {
135-
pendingResult = result;
144+
pendingFrameworkRequest = result;
136145
}
137146
break;
138147
default:

0 commit comments

Comments
 (0)