1. Introduction

In the Article Flutter Framework Analysis (VIII) -Platform Channel, we analyzed the principle and structure of MethodChannel and explained some of its core classes in detail, such as MethodCallHandler and MethodCodec. This article focuses on an example using MethodChannel.

2. Usage process

The MethodChannel can be used both the way the Flutter calls native and the way the native calls the Flutter, so we’ll analyze each usage flow separately.

2.1 The Flutter calls native methods

The process is as follows:

1) Create a MethodChannel on the native side.

2) the native end uses setMethodCallHandler to set the MethodCallHandler for this MethodChannel.

3) The Flutter side creates a MethodChannel for this channel name.

4) The Flutter end uses this MethodChannel to send method calls to the native end through the invokeMethod function, passing the method name and method parameters.

5) The newly registered MethodCallHandler on the native side receives the sent message, processes the message in onMethodCall, and replies through the reply function.

6) Handle the response at the Flutter end.

The key code for the Flutter side is as follows:

class _MyHomePageState extends State<MethodChannelWidget> {
  static const nativeChannel = const MethodChannel('flutter2/MethodChannel');
  int _counter = 0;

  void _incrementCounter() async {
    setState(() {
      _counter++;
    });
    String result = await nativeChannel.invokeMethod('getJavaMethod'."123");
    print('methodChannelTest _incrementCounter: + $result');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("method channel test"),
      ),
      body: Center(
      child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),  // This trailing comma makes auto-formatting nicer for build methods.); }}Copy the code

The key code on the native side is as follows:

class MethodChannelActivity : FlutterActivity() {
    private var mFlutter2MethodChannel: MethodChannel? = null

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        Log.d("FirstNativeActivity"."configureFlutterEngine")
        initChannel(flutterEngine)
    }

    private fun initChannel(flutter2Engine: FlutterEngine) {
        mFlutter2MethodChannel = MethodChannel(flutter2Engine.dartExecutor, "flutter2/MethodChannel") mFlutter2MethodChannel!! .setMethodCallHandler(MethodCallHandler {call, result -> Log.e("methodChannelTest"."onMethodCall method:" + call.method)
            if ("getJavaMethod" == call.method) {
                result.success("success ")
                Log.e("methodChannelTest"."success:" + call.arguments())
            } else {
                result.success(" unKnow method")}}}companion object {
        fun startActivity(activity: Activity) {
            val intent = Intent(activity, MethodChannelActivity::class.java)
            activity.startActivity(intent)
        }
    }
}
Copy the code

2.2 Native calls the Flutter end method

The process is as follows:

1) The Flutter side creates a MethodChannel for the channel name.

2) Set the Handler function for this MethodChannel using setMethodCallHandler on the Flutter side.

3) Create a MethodChannel on the native side.

4) The native end uses this MethodChannel to send messages to the Flutter end through the invokeMethod function, passing the method name and method parameters.

5) The newly registered Handler on the Flutter side receives the sent message, processes the message, and then replies via the reply function.

6) The native side processes the reply.

The key code for the Flutter side is as follows:

class _MyHomePageState extends State<MethodChannelWidget> {
  static const nativeChannel = const MethodChannel('flutter2/MethodChannel');
  int _counter = 0;

  @override
  void initState() {
    nativeChannel.setMethodCallHandler(flutterMethod);
    super.initState();
  }

  Future<dynamic> flutterMethod(MethodCall methodCall) async {
    switch (methodCall.method) {
      case 'flutterMethod':
        print('methodChannelTest native Android calls flutterMethod with argument: '+methodCall.arguments);
        return "hahaha"; }}}Copy the code

The key code on the native side is as follows:

class MethodChannelActivity : FlutterActivity() {
    private var mFlutter2MethodChannel: MethodChannel? = null
    private var mHandler: Handler? = null
    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState) mHandler = Handler() mHandler!! .postDelayed( { Log.e("methodChannelTest"."getJavaMethod invokeFlutterMethod_toAllFlutter")
            invokeFlutterMethod_toAllFlutter()
         } , 3000)}override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        Log.d("FirstNativeActivity"."configureFlutterEngine")
        initChannel(flutterEngine)
    }

    private fun initChannel(flutter2Engine: FlutterEngine) {
        mFlutter2MethodChannel = MethodChannel(flutter2Engine.dartExecutor, "flutter2/MethodChannel")}private fun invokeFlutterMethod_toAllFlutter(a) {
        if(mFlutter2MethodChannel ! =null) { mFlutter2MethodChannel!! .invokeMethod("flutterMethod"."I'm native Android and I'm passing parameters to a method in my Flutter.".object : MethodChannel.Result {
                override fun success(o: Any?). {
                    Log.d("methodChannelTest"."flutterMethod:$o")}override fun error(s: String, s1: String? , o:Any?). {}
                override fun notImplemented(a){}}}})companion object {
        fun startActivity(activity: Activity) {
            val intent = Intent(activity, MethodChannelActivity::class.java)
            activity.startActivity(intent)
        }
    }
}
Copy the code

3. Summary

This article mainly introduces the flow of using MethodChannel and gives an example of using MethodChannel.