mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
A continuation of https://github.com/flutter/flutter/pull/177127. Copying from there: # Overview > [!NOTE] > This PR is based on conversation & feedback on go/flutter-android-harden-engine-shell-arguments. Adds a mechanism for setting Android engine flags via the manifest. If a flag is specified on the command line and in manifest metadata, the value specified on the command line will take precedence. Documentation is added on this mechanism Additionally, this PR removes the exposure of`--cache-sksl` command line flag as per [https://github.com/flutter/flutter/issues/140310#issuecomment-2708459007](https://www.google.com/url?q=https://github.com/flutter/flutter/issues/140310%23issuecomment-2708459007&sa=D&source=docs&ust=1761156167162464&usg=AOvVaw3a8ubXTtv3apknY2-P9dKe). Additionally, this PR adds documentation for the only two supported ways of setting engine flags moving forward -- via the command line or manifest. The `Intent` mechanism will be removed when https://github.com/flutter/flutter/issues/180686 is completed (intended to be a follow up to this PR). As the unit tests in this PR only cover setting flags via manifest in debug mode, I will follow up this PR with an integration test to test that flags are appropriately respected/ignored in release mode. See https://github.com/flutter/flutter/pull/178383 for my currently working but WIP draft. Part of https://github.com/flutter/flutter/issues/172553. # Follow up work: ## Add integration test for this new added mechanism This will land as an immediate follow-up to this PR. WIP in https://github.com/flutter/flutter/pull/178383. ## Remove support for setting shell arguments via `Intent` This task will be a follow up to this work + the integration test landing, and will complete work for https://github.com/flutter/flutter/issues/172553. See https://github.com/flutter/flutter/issues/180686 for details. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
191 lines
6.4 KiB
Markdown
191 lines
6.4 KiB
Markdown
# Setting Flutter Android engine flags
|
|
|
|
You can set flags for the Flutter engine on Android in two different ways:
|
|
|
|
- From the command line when launching an app with the Flutter tool
|
|
- Via `AndroidManifest.xml` metadata (static, per-build configuration)
|
|
|
|
All flags available on Android can be set via the command line **and** via
|
|
manifest metadata. See `src/flutter/shell/common/switches.cc` for
|
|
the list of all supported flags, and see
|
|
`src/flutter/shell/platform/android/io/flutter/embedding/engine/`
|
|
`FlutterShellArgs.java` for the list of flags that can be set for the
|
|
Android shell.
|
|
|
|
## When to use manifest metadata versus the command line
|
|
|
|
Use the manifest when:
|
|
|
|
- You want a fixed, reproducible baseline of engine flags
|
|
for your app across all launches. This is ideal for CI and for enforcing a
|
|
consistent configuration for your app.
|
|
- You want to vary flags by build mode or product flavor
|
|
via manifest merging. For example, place metadata in
|
|
`src/debug/AndroidManifest.xml`, `src/profile/AndroidManifest.xml`, and
|
|
`src/release/AndroidManifest.xml` (or per-flavor manifests) to tailor flags
|
|
per variant.
|
|
|
|
Use the command line when:
|
|
|
|
- You want to quickly experiment with a flag for a single run of your app.
|
|
- You need to override a flag that is already set in the manifest temporarily for debugging
|
|
or testing purposes.
|
|
|
|
**Note: If a flag is specified both on the command line and in the manifest,
|
|
the command-line value takes precedence at runtime.**
|
|
|
|
See below for details on using each method.
|
|
|
|
## How to set engine flags from the command line
|
|
|
|
When you run a standalone Flutter app with the Flutter tool, engine flags
|
|
can be passed directly and are forwarded to the Android engine. Examples:
|
|
|
|
```bash
|
|
flutter run --trace-startup \
|
|
--enable-software-rendering \
|
|
--dart-flags="--enable-asserts"
|
|
```
|
|
|
|
Notes:
|
|
|
|
- Flags that take values use the `--flag=value` form (with `=`). The Flutter
|
|
tool forwards them in that form to the Android embedding.
|
|
|
|
## How to set engine flags in the manifest
|
|
|
|
All manifest metadata keys must be prefixed with the package name
|
|
`io.flutter.embedding.android` and are suffixed with the metadata name for the
|
|
related command line flag as determined in
|
|
`src/flutter/shell/platform/android/io/flutter/embedding/engine/`
|
|
`FlutterShellArgs.java`. For example, the `--impeller-lazy-shader-mode=`
|
|
command line flag corresponds to the metadata key
|
|
`io.flutter.embedding.android.ImpellerLazyShaderInitialization`.
|
|
|
|
For flags that take values, set the numeric, string, or boolean value (without
|
|
the leading `--flag=` prefix).
|
|
|
|
### Examples
|
|
|
|
Set the `--old-gen-heap-size=` flag to 322 MB:
|
|
|
|
```xml
|
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
package="com.example.myapp">
|
|
<application ...>
|
|
<meta-data
|
|
android:name="io.flutter.embedding.android.OldGenHeapSize"
|
|
android:value="322"/>
|
|
...
|
|
</application>
|
|
</manifest>
|
|
```
|
|
|
|
Set the `--enable-flutter-gpu` flag:
|
|
|
|
```xml
|
|
<meta-data
|
|
android:name="io.flutter.embedding.android.EnableFlutterGPU"
|
|
/>
|
|
```
|
|
|
|
## Release-mode restrictions
|
|
|
|
- Some flags are not allowed in release mode. The Android embedding enforces
|
|
this policy (see `src/flutter/shell/platform/android/io/flutter/
|
|
embedding/engine/FlutterShellArgs`, which marks allowed flags
|
|
with `allowedInRelease`). If a disallowed flag is set in release, it will
|
|
be ignored.
|
|
- If you need different behavior in release vs debug/profile mode, configure it
|
|
via variant-specific manifests or product flavors.
|
|
|
|
## How to set engine flags dynamically
|
|
|
|
As of the writing of this document, setting Flutter shell arguments via an
|
|
Android `Intent` is no longer supported. If you need per-launch or
|
|
runtime-controlled flags in an add-to-app integration, you may do so
|
|
programatically before engine initialization.
|
|
|
|
To do that, supply engine arguments directly to a `FlutterEngine` with the
|
|
desired flags from the earliest point you can control in your
|
|
application. For example, if you are writing an add-to-app app that launches
|
|
a `FlutterActivity` or `FlutterFragment`, then you can cache a
|
|
`FlutterEngine` that is initialized with your desired
|
|
engine flags:
|
|
|
|
```kotlin
|
|
// Your native Android application
|
|
class MyApp : Application() {
|
|
override fun onCreate() {
|
|
super.onCreate()
|
|
// Initialize the Flutter engine with desired flags
|
|
val args = arrayOf(
|
|
"--trace-startup",
|
|
"--old-gen-heap-size=256",
|
|
"--enable-software-rendering"
|
|
)
|
|
val flutterEngine = FlutterEngine(this, args)
|
|
|
|
// Start executing Dart code in the FlutterEngine
|
|
flutterEngine.dartExecutor.executeDartEntrypoint(
|
|
DartEntrypoint.createDefault()
|
|
)
|
|
|
|
// Store the engine in the cache for later use
|
|
FlutterEngineCache.getInstance().put("my_engine_id", flutterEngine)
|
|
}
|
|
}
|
|
```
|
|
|
|
Then, your `Activity` can launch a `FlutterActivity` or `FlutterFragment`
|
|
with that cached `FlutterEngine`:
|
|
|
|
```kotlin
|
|
// Start a FlutterActivity using the cached engine...
|
|
val intent = FlutterActivity.withCachedEngine("my_engine_id").build(this)
|
|
startActivity(intent)
|
|
|
|
// Or launch a FlutterFragment using the cached engine
|
|
val flutterFragment = FlutterFragment.withCachedEngine("my_engine_id").build()
|
|
supportFragmentManager
|
|
.beginTransaction()
|
|
.add(R.id.fragment_container, flutterFragment, TAG_FLUTTER_FRAGMENT)
|
|
.commit()
|
|
```
|
|
|
|
For a normal Flutter Android app, you can create and initialize a `FlutterEngine`
|
|
with your desired flags the same as in the example above, then override
|
|
`provideFlutterEngine` in your app's `FlutterActivity` to provide the
|
|
configured `FlutterEngine`. For example:
|
|
|
|
```kotlin
|
|
// Your Flutter Android application
|
|
class MyApplication : FlutterApplication() {
|
|
override fun onCreate() {
|
|
super.onCreate()
|
|
|
|
val args = arrayOf(
|
|
"--trace-startup",
|
|
"--old-gen-heap-size=256",
|
|
"--enable-software-rendering"
|
|
)
|
|
val flutterEngine = FlutterEngine(this, args)
|
|
flutterEngine.dartExecutor.executeDartEntrypoint(
|
|
DartExecutor.DartEntrypoint.createDefault()
|
|
)
|
|
FlutterEngineCache
|
|
.getInstance()
|
|
.put(MY_ENGINE_ID, flutterEngine)
|
|
}
|
|
}
|
|
|
|
// Your Flutter Android Activity
|
|
class MainActivity: FlutterActivity() {
|
|
override fun provideFlutterEngine(context: Context): FlutterEngine? {
|
|
return FlutterEngineCache
|
|
.getInstance()
|
|
.get(MyApplication.MY_ENGINE_ID)
|
|
}
|
|
}
|
|
```
|