Flutter - Dart代码调用Android原生代码

Flutter – Dart代码调用Kotlin原生代码

背景

开发中,我们常常需要调用原生Android的代码,因此我们需要通过一种方式来传递调用结果或者执行某个过程。在Flutter开发中,官方给我们提供了比较方便的方式来处理这种问题。MethodChannel, 顾名思义,方法渠道,也可以理解为一种通讯方式。

如何使用?

可能一些朋友对官方文档看得有点迷糊,这里我用我所理解并写出的案例帮助大家学习。举个栗子,开发中,我们使用最多的Toast消息框,但是Flutter并不提供Toast相关方法,那么我们就要自己造轮子把Toast从原生代码引入Dart代码中。

  • ToastProviderPlugin – 提供Toast相关的方法,提供Toast注册到Flutter中

    object ToastProviderPlugin {
    
        /** Channel名称  **/
        private const val ChannelName = "com.mrper.framework.plugins/toast"
    
        /**
         * 注册Toast插件
         * @param context 上下文对象
         * @param messenger 数据信息交流对象
         */
        @JvmStatic
        fun register(context: Context, messenger: BinaryMessenger) = MethodChannel(messenger, ChannelName).setMethodCallHandler { methodCall, result ->
            when (methodCall.method) {
                "showShortToast" -> showToast(context, methodCall.argument<String>("message"), Toast.LENGTH_SHORT)
                "showLongToast" -> showToast(context, methodCall.argument<String>("message"), Toast.LENGTH_LONG)
                "showToast" -> showToast(context, methodCall.argument<String>("message"), methodCall.argument<Int>("duration"))
            }
            result.success(null) //没有返回值,所以直接返回为null
        }
    
        private fun showToast(context: Context, message: String, duration: Int) = Toast.makeText(context, message, duration).show()
    
    }
    
  • MainActivity – 注册Toast插件,不然Flutter无法调用

    class MainActivity() : FlutterActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            GeneratedPluginRegistrant.registerWith(this)
            ToastProviderPlugin.register(this, flutterView) //注册Toast插件
        }
    }
    
  • main.dart – Dart语言中调用Toast插件, 重要类MethodChannel (源自’package:flutter/services.dart’)

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
    
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      //声明一个调用对象,需要把kotlin中注册的ChannelName传入构造函数
      static const _platform = const MethodChannel('com.mrper.framework.plugins/toast');
    
      void _incrementCounter() {
        _platform.invokeMethod('showShortToast', { 'message': '你点击了按钮!'}); //调用相应方法,并传入相关参数。
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text(widget.title),
          ),
          body: new Center(
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text(
                  'You have pushed the button this many times:',
                ),
                new Text(
                  'fsfsfsdfsdf',
                  style: Theme
                      .of(context)
                      .textTheme
                      .display1,
                ),
              ],
            ),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: new Icon(Icons.add),
          ),
        );
      }
    }
    
    
  • Toast可以在Dart语言中重新组装一下,以方便调用

     import 'package:flutter/services.dart';
    
     class Toast {
    
       static const _platform = const MethodChannel("com.mrper.framework.plugins/toast");
    
       static void showShortToast(String message) =>
           _platform.invokeMethod("showShortToast", { "message": message});
    
       static void showLongToast(String message) =>
           _platform.invokeMethod("showLongToast", { "message": message});
    
       static void showToast(String message, int duration) =>
           _platform.invokeMethod(
               "showToast", { "message": message, "duration": duration});
    
     }
    

结论:使用Dart调用Kotin语言,重点是MethodCall,以及如何通过MethodCall获取相对应的方法名和方法参数。然后,Dart中根据原生定义的方法名及参数传入相对应的对象即可。

    原文作者:Cosecant
    原文地址: https://www.jianshu.com/p/406fe6c1edcb
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞