I want to add a Flutter Module
into an existing Android
application. I'm doing this theoretically but I couldn't get exactly the result I wanted. Because I'm using Flutter Cache Engine
and when the Android application is run, my Flutter module also starts running. Since the InitState
method is running, I cannot automatically display the data on the screen even if I switch to the Flutter side. To solve this, I defined Route
in Flutter. In this way, my Flutter module starts from the /root
screen and if I open the /home
screen directly by triggering from Android, my initState
method works. But I can't trigger this route through my android application. setInitialRoute
didn't solve my problem, I used pushRoute
but this time when the back button is pressed, it returns to /root
route not to android application. I can't think of a solution other than changing the functionality of the device's back button every time I add a screen. What is the practical or correct way to do this? This is important as I will have several screens that will be triggered by android app side. Thank you in advance for your help.
MainApplication.kt:
const val FULL_SCREEN_ENGINE_ID = "fullScreenEngineId"
class MainApplication: Application(){
override fun onCreate() {
super.onCreate()
val flutterEngineFullScreen = FlutterEngine(this);
flutterEngineFullScreen.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
FlutterEngineCache.getInstance().put(FULL_SCREEN_ENGINE_ID, flutterEngineFullScreen)
}
}
MainActivity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sendButton = findViewById<Button>(R.id.button)
val nameInput = findViewById<EditText>(R.id.editTextText)
val editInput = findViewById<EditText>(R.id.editTextTextEmailAddress)
sendButton.setOnClickListener {
val dataMap = hashMapOf(
"name" to nameInput.text.toString(),
"email" to editInput.text.toString()
)
val intent = Intent(this, CustomFlutterActivity::class.java)
intent.putExtra("nameAndEmail", dataMap)
startActivity(intent)
}
}
}
CustomFlutterActivty:
class CustomFlutterActivity: FlutterActivity() {
companion object{
const val CHANNEL = "net.ahmettalha.flutteroid_app"
const val FULL_SCREEN_ENGINE_ID = "fullScreenEngineId"
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
.setMethodCallHandler { call, result ->
when(call.method){
"goToFlutterWithData" -> {
Log.e("nameAndEmail", [email protected]("nameAndEmail").toString())
result.success([email protected]("nameAndEmail"))
}
else -> result.notImplemented()
}
}
}
override fun provideFlutterEngine(context: Context): FlutterEngine? {
val flutterEngine = FlutterEngineCache.getInstance().get(FULL_SCREEN_ENGINE_ID)
if (flutterEngine != null){
Log.i("route fe", "engine not null")
flutterEngine!!.navigationChannel.setInitialRoute("/home")
}
return flutterEngine
}
}
Flutter MyApp:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
ColorScheme _colorScheme = ColorScheme.fromSeed(
seedColor: const Color.fromARGB(255, 209, 121, 5), brightness: Brightness.light);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData().copyWith(useMaterial3: true, colorScheme: _colorScheme),
routes: {
"/root": (context) => const RootPage(),
"/home": (context) => const HomeScreen(),
},
home: const RootPage(),
);
}
}
The solution is to pass the route like below:
Flutter engine will automatically find and go to
/flutter_route