Flutter - Dart代碼調(diào)用Kotlin原生代碼
背景
開發(fā)中望门,我們常常需要調(diào)用原生Android的代碼篮迎,因此我們需要通過一種方式來傳遞調(diào)用結(jié)果或者執(zhí)行某個(gè)過程男图。在Flutter開發(fā)中示姿,官方給我們提供了比較方便的方式來處理這種問題甜橱。MethodChannel, 顧名思義,方法渠道栈戳,也可以理解為一種通訊方式岂傲。
如何使用?
可能一些朋友對(duì)官方文檔看得有點(diǎn)迷糊子檀,這里我用我所理解并寫出的案例幫助大家學(xué)習(xí)镊掖。舉個(gè)栗子乃戈,開發(fā)中,我們使用最多的Toast消息框亩进,但是Flutter并不提供Toast相關(guān)方法症虑,那么我們就要自己造輪子把Toast從原生代碼引入Dart代碼中。
-
ToastProviderPlugin - 提供Toast相關(guān)的方法归薛,提供Toast注冊(cè)到Flutter中
object ToastProviderPlugin { /** Channel名稱 **/ private const val ChannelName = "com.mrper.framework.plugins/toast" /** * 注冊(cè)Toast插件 * @param context 上下文對(duì)象 * @param messenger 數(shù)據(jù)信息交流對(duì)象 */ @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 - 注冊(cè)Toast插件,不然Flutter無法調(diào)用
class MainActivity() : FlutterActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) GeneratedPluginRegistrant.registerWith(this) ToastProviderPlugin.register(this, flutterView) //注冊(cè)Toast插件 } }
-
main.dart - Dart語言中調(diào)用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> { //聲明一個(gè)調(diào)用對(duì)象主籍,需要把kotlin中注冊(cè)的ChannelName傳入構(gòu)造函數(shù) static const _platform = const MethodChannel('com.mrper.framework.plugins/toast'); void _incrementCounter() { _platform.invokeMethod('showShortToast', { 'message': '你點(diǎn)擊了按鈕习贫!'}); //調(diào)用相應(yīng)方法,并傳入相關(guān)參數(shù)千元。 } @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語言中重新組裝一下苫昌,以方便調(diào)用
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}); }
結(jié)論:使用Dart調(diào)用Kotin語言,重點(diǎn)是MethodCall幸海,以及如何通過MethodCall獲取相對(duì)應(yīng)的方法名和方法參數(shù)祟身。然后,Dart中根據(jù)原生定義的方法名及參數(shù)傳入相對(duì)應(yīng)的對(duì)象即可涕烧。