Flutter 项目使用MethodChannel撰写双端平台代码(相互通信)

343 阅读1分钟

一、简介

Flutter 作为一个跨平台UI框架,很多原生的功能无法实现,因此我们可以在Flutter中和其他平台通信调用对应平台的能力,在Flutter 中使用MethodChannel编写双端代码,相互通信,本文以Android为例,其他各个平台参考官网 flutter.cn/docs/packag…

二、实现

1、定义平台通信唯一通道

  private val CHANNEL = "samples.flutter.dev/battery"

2、编写Android代码

package com.example.batterylevel

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "samples.flutter.dev/battery"

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        //设置dart调用kotlin的函数监听
        channel.setMethodCallHandler {
            // This method is invoked on the main thread.
                call, result ->
            if (call.method == "getBatteryLevelFromAndroid") {
                val args = mapOf("batteryLevel" to "999")
                //在android又调用dart中的函数
                channel.invokeMethod(
                    "getBatteryLevelFromDart",
                    args,
                    object : MethodChannel.Result {
                        override fun success(value: Any?) {
                            //设置结果
                            result.success("value is ${value}")
                        }

                        override fun error(
                            errorCode: String,
                            errorMessage: String?,
                            errorDetails: Any?
                        ) {
                        }

                        override fun notImplemented() {
                        }

                    })
                //  result.success("11111111111")
            } else {
                result.notImplemented()
            }
        }


    }


}

3、编写flutter代码

```
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        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> {
  static const platform = MethodChannel('samples.flutter.dev/battery');

  @override
  void initState() {
    super.initState();
    //监听android调用过来
    platform.setMethodCallHandler((call) async {
      var method = call.method;
      var arguments = call.arguments;
      print('method:${method} and arguments:${arguments}');
      if (method == "getBatteryLevelFromDart") {
        String battery = await getBatteryLevelFromDart();
        return battery;
      }
    });
  }

  Future<String> getBatteryLevelFromDart() async {
    return "888";
  }

// Get battery level.
  String _batteryLevel = 'Unknown battery level.';

  Future<void> _getBatteryLevelFromAndroid() async {
    String batteryLevel;
    try {
      //在dart中调用android中的函数
      final String result =
          await platform.invokeMethod('getBatteryLevelFromAndroid');
      batteryLevel = 'Battery level at $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }
    setState(() {
      _batteryLevel = batteryLevel;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text(widget.title),
        ),
        body: Center(
            child: Column(
          children: [
            Text("_batteryLevel is : ${_batteryLevel}"),
            TextButton(
                onPressed: () async {
                  _getBatteryLevelFromAndroid();
                },
                child: Text("getBatteryLevelFromAndroid}"))
          ],
        )));
  }
}
```

以上我们实现了从flutter中调用了android平台的getBatteryLevelFromAndroid函数,在android中又调用了flutter中的getBatteryLevelFromDart函数,getBatteryLevelFromDart函数返回了一个888,在android中接受到888,又将888返回给flutter,一次性实现了双向通信。以上核心代码都是通过以下实现:

val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) 
channel.setMethodCallHandler {

三、注意

我们首先要通过flutter create demo 创建flutter项目

  • 1、编写flutter代码的时候,我们可以直接通过android studio工具打开项目的根目录

  • 2、编写android代码的时候,我们可以通过file-open打开android这个目录,这样我们在写kotlin代码的时候就不会爆红,并且有提示。