How to pass data from android module to flutter module in flutter

Viewed 3060

I have successfully integrated flutter module in my native android application by following steps here .

The process of caching flutter engine I have already done in Application class. I am launching my flutter screen with this from android fragment.

startActivity(
      FlutterActivity
        .withCachedEngine("my_engine_id")
        .build(currentActivity)
      );

Now I want to pass my auth token to flutter module for making api calls.

I am following the process from here and created method channel in dart code but I do not know where to create the method channel in the native side.

If I am creating it in project/moduleName/.android/app/src/main/java/com/package/host/MainActivity.java

It is giving exception Unhandled Exception: MissingPluginException(No implementation found for method

Also note that this folder is placed in .gitignore by default when I created this flutter module in Android studio.

I already has a look at older tutiorals but this caching of flutter engine option is not there in them.

Please tell where am I doing wrong ?

3 Answers

You need to have a reference for the Flutter Engine and then use it to create the Method Channel. Take in account that the activity/fragment that launch the Flutter activity is in charge to manage the Method Channel.

private const val FLUTTER_ENGINE_ID = "flutter_engine"
private const val CHANNEL = "myApp.flutter.dev/auth"

class MainActivity : AppCompatActivity(R.layout.activity_main) {

    private lateinit var flutterEngine: FlutterEngine

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setupFlutterEngine()
        setupMethodChannel()
        setSupportActionBar(findViewById(R.id.toolbar))

        fab.setOnClickListener {
            launchFlutterModule()
        }
    }

    private fun setupFlutterEngine() {
        createAndConfigureFlutterEngine()
        FlutterEngineCache
            .getInstance()
            .put(FLUTTER_ENGINE_ID, flutterEngine)
    }

    private fun createAndConfigureFlutterEngine() {
        flutterEngine = FlutterEngine(this)
        flutterEngine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
    }

    private fun setupMethodChannel() {
        MethodChannel(
            flutterEngine.dartExecutor.binaryMessenger,
            CHANNEL
        ).setMethodCallHandler { call, result ->
            // All your implementation for auth token
        }
    }

    private fun launchFlutterModule() {
        startActivity(getFlutterIntent())
    }

    private fun getFlutterIntent(): Intent {
        return FlutterActivity
            .withCachedEngine(FLUTTER_ENGINE_ID)
            .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
            .build(this)
    }
}

You can make a Wrapper where you can hold the method channel code and flutter engine setup, and this wrapper is init in your Application class or maybe init and injected with Dagger or Hilt where is needed.

You can pass simple data as request parameters. Android code:

FlutterActivity
    .withNewEngine()
    .initialRoute("/MyPage?username=my_user&age=30&gender=male")
    .build(MainActivity.this)

Flutter code, I use GetX library to get the parameters

Map<String, String?> parameters = Get.parameters;
print("parameters: $parameters");

Output:

parameters: {username: my_user, age: 30, gender: male}
Related