Skip to content

Using Material 3 on Android, the Status Bar color changes when using Flutter Engine Cache #150418

@shin-ichiro-matsui

Description

@shin-ichiro-matsui

Steps to reproduce

We use FlutterEngineGroup and FlutterEngineCache in our application.
This is because we are incorporating Flutter screens into an existing native application.

The steps to reproduce the issue are as follows:

  1. Launch the application.
  2. Perform initialization processing in the Android app.
  3. Call up the Flutter screen using FlutterEngineGroup and FlutterEngineCache.
  4. Exit the Flutter screen with the back key. The cache is not discarded in this case.
  5. Launch the Flutter screen again using the cached FlutterEngine.

When you perform the above operations, the color of the Status Bar will change.

Expected results

The status bar color should remain the same.

Actual results

If you discard the cache and start a new engine this problem doesn't seem to occur.

Code sample

We will prepare a minimal sample that will allow you to confirm the phenomenon.

Code sample in Flutter
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
Code sample in Android
  • application class
package com.example.status_bar_test;

import android.app.Application;

import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.FlutterEngineGroup;

public final class SampleApplication extends Application {
    public FlutterEngineGroup engineGroup;

    @Override
    public void onCreate() {
        super.onCreate();
        engineGroup =  new FlutterEngineGroup(this);
        final FlutterEngine mainFlutterEngine = engineGroup.createAndRunDefaultEngine(this);
        FlutterEngineCache.getInstance().put("main", mainFlutterEngine);
    }
}
  • demo first activity
package com.example.status_bar_test;

import android.app.Activity;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;

public class InitializeActivity extends Activity {

    @Override
    protected void onResume() {
        super.onResume();
        // ..run initialization process
        final String enginId = "main";
        if (!FlutterEngineCache.getInstance().contains(enginId)) {
            final FlutterEngine mainFlutterEngine = ((SampleApplication)getApplication()).engineGroup.createAndRunDefaultEngine(this);
            FlutterEngineCache.getInstance().put("main", mainFlutterEngine);
        }
        startActivity(new FlutterActivity.CachedEngineIntentBuilder(MainActivity.class, enginId).build(this));
        finish();
    }
}
  • main activity
package com.example.status_bar_test;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngineCache;

public class MainActivity extends FlutterActivity {

    @Override
    protected void onDestroy() {
        // FlutterEngineCache.getInstance().remove("main");
        super.onDestroy();
    }
}
  • AndroidManifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:name=".SampleApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="status_bar_test">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:exported="true"
            android:hardwareAccelerated="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:windowSoftInputMode="adjustResize">
            <meta-data
                android:name="io.flutter.embedding.android.NormalTheme"
                android:resource="@style/NormalTheme" />
        </activity>
        <activity
            android:name=".InitializeActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
    <!-- Required to query activities that can process text, see:
         https://developer.android.com/training/package-visibility?hl=en and
         https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

         In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
    <queries>
        <intent>
            <action android:name="android.intent.action.PROCESS_TEXT" />
            <data android:mimeType="text/plain" />
        </intent>
    </queries>
</manifest>

Screenshots or Video

Screenshots / Video demonstration
Screen_recording_20240618_192803.mp4

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.19.2, on macOS 14.4.1 23E224 darwin-arm64, locale ja-JP)
    • Flutter version 3.19.2 on channel stable at /Users/fvm/versions/3.19.2
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 7482962148 (4 months ago), 2024-02-27 16:51:22 -0500
    • Engine revision 04817c99c9
    • Dart version 3.3.0
    • DevTools version 2.31.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15F31d
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] VS Code (version 1.77.1)
    • VS Code at /Users/Downloads/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (3 available)
    • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64  • Android 12 (API 32) (emulator)
    • macOS (desktop)             • macos         • darwin-arm64   • macOS 14.4.1 23E224 darwin-arm64
    • Chrome (web)                • chrome        • web-javascript • Google Chrome 126.0.6478.61

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listengineflutter/engine related. See also e: labels.found in release: 3.22Found to occur in 3.22found in release: 3.23Found to occur in 3.23has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions