Prevent App Restart When Applying Wallpaper in Flutter
Introduction
In Android 12 and above, Google implements a feature called Dynamic Colors.
It allows the system to change the colors of the app based on the wallpaper. This is a great feature, but it has a problem. When you apply wallpaper, the app restarts. This occurs because it’s a configChanges
, so all activities are restarted.
In the last few days, I was working on a Flutter project that required the user to be able to change the system wallpaper. I was looking for a way to prevent the app from restarting when the wallpaper is changed. I found a solution, and I’m going to share it with you.
Solution
The solution in a Flutter project is to use a FlutterEngineCache. It’s a cache that stores FlutterEngines and this cache will prevent the app from restarting when the wallpaper is changed.
Simple Example
In the android
folder of your Flutter project, create a new file called MyAppApplication.kt
and add the following code:
package com.example.myapp
import android.app.Application
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.embedding.engine.dart.DartExecutor
class MyAppApplication : Application() {
override fun onCreate() {
super.onCreate()
// Create a FlutterEngine instance.
flutterEngine = FlutterEngine(this)
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
// Cache the FlutterEngine to be used by FlutterActivity.
// You can use any identifier
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine)
}
}
After that, in the AndroidManifest.xml
file, add the following code:
<application
android:name=".MyAppApplication"
...>
...
Then, in your MainActivity.kt
, add the following code:
class MainActivity : FlutterActivity() {
override fun provideFlutterEngine(context: Context): FlutterEngine? {
// The same identifier used in the MyAppApplication.kt
return FlutterEngineCache.getInstance().get("my_engine_id")
}
@RequiresApi(Build.VERSION_CODES.N)
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "you_channel_name")
.setMethodCallHandler { call, result ->
when (call.method) {
"set_wallpaper" -> {/* handle wallpaper change */}
else -> result.notImplemented()
}
}
}
}
Now, you can call the set_wallpaper
method from your Flutter code and this prevents the app from restarting.