在本节中, 我们将看到如何在Flutter中编写自定义平台特定的代码。 Flutter是一个出色的框架, 它提供了一种机制来处理/访问特定于平台的功能。此功能使开发人员可以扩展Flutter框架的功能。可以通过该框架轻松访问的一些特定于平台的基本功能包括相机, 电池电量, 浏览器等。
Flutter使用灵活的系统来调用特定于平台的API, 该API在Android上可用Java或Kotlin代码在iOS中可用, 在Objective-C或Swift代码中可用。在Flutter中访问特定于平台的代码的总体思路是通过消息传递协议。消息使用公共消息通道在客户端(UI)和主机(平台)之间传递。这意味着客户端使用此消息通道将消息发送到主机。接下来, 主机在该消息通道上侦听, 接收消息, 执行适当的功能, 最后将结果返回给客户端。
以下框图显示了适当的平台特定的代码体系结构。
文章图片
消息传递通道使用标准消息编解码器(StandardMessageCodec类), 该编解码器支持对JSON之类的值(例如字符串, 布尔值, 数字, 字节缓冲区以及List和Maps等)进行有效的二进制序列化。这些值的序列化和反序列化将自动进行发送和接收值时客户端和主机之间的连接。
下表显示了如何在Android和iOS平台上接收飞镖值, 反之亦然:
镖 | 安卓系统 | 的iOS |
---|---|---|
null | null | nil (NSNull when nested) |
bool | java.lang.Boolean | NSNumber numberWithBool: |
int | java.lang.Integer | NSNumber numberWithInt: |
double | java.lang.Double | NSNumber numberWithDouble: |
String | java.lang.String | NSString: |
Uint8List | byte[] | FlutterStandardTypedData typedDataWithBytes: |
Int32List | int[] | FlutterStandardTypedData typedDataWithInt32: |
Int64List | long[] | FlutterStandardTypedData typedDataWithInt64: |
Float64List | double[] | FlutterStandardTypedData typedDataWithFloat64: |
List | 的java.util.ArrayList | NSArray |
Map | java.util.HashMAp | NSDictionary |
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
void main() =>
runApp(MyApp());
class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter DemoApplication', theme: ThemeData(primarySwatch: Colors.green, ), home: MyHomePage(title: 'Flutter Platform Specific Page'), );
}}class MyHomePage extends StatelessWidget {MyHomePage({Key key, this.title}) : super(key: key);
final String title;
static const platform = const MethodChannel('flutterplugins.srcmini.com/browser');
Future<
void>
_openBrowser() async {try {final int result = await platform.invokeMethod('openBrowser', <
String, String>
{'url': "https://www.srcmini.com"});
}on PlatformException catch (e) {// Unable to open the browserprint(e);
}}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(this.title), ), body: Center(child: RaisedButton(child: Text('Click Here'), onPressed: _openBrowser, ), ), );
}}
在上面的文件中, 我们导入了service.dart文件, 该文件包含调用平台特定代码的功能。在MyHomePage小部件中, 我们创建了一个消息通道并编写了_openBrowser方法来调用特定于平台的代码。
Future<
void>
_openBrowser() async {try {final int result = await platform.invokeMethod('openBrowser', <
String, String>
{'url': "https://www.srcmini.com"});
}on PlatformException catch (e) {// Unable to open the browser print(e);
}}
最后, 我们创建了一个打开浏览器的按钮。
现在, 我们需要提供定制平台特定的实现。为此, 请导航至Flutter项目的Android文件夹, 然后选择Java或Kotlin文件, 并将以下代码插入MainActivity文件。该代码可能会根据Java或Kotlin语言而更改。
package com.srcmini.flutterplugins.flutter_demoapplicationimport android.app.Activityimport android.content.Intentimport android.net.Uriimport android.os.Bundleimport io.flutter.app.FlutterActivityimport io.flutter.plugin.common.MethodCallimport io.flutter.plugin.common.MethodChannelimport io.flutter.plugin.common.MethodChannel.MethodCallHandlerimport io.flutter.plugin.common.MethodChannel.Resultimport io.flutter.plugins.GeneratedPluginRegistrant class MainActivity:FlutterActivity() {override fun onCreate(savedInstanceState:Bundle?) {super.onCreate(savedInstanceState)GeneratedPluginRegistrant.registerWith(this)MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->
val url = call.argument<
String>
("url")if (call.method == "openBrowser") {openBrowser(call, result, url)} else {result.notImplemented()}} } private fun openBrowser(call:MethodCall, result:Result, url:String?) {val activity = thisif (activity == null){result.error("UNAVAILABLE", "It cannot open the browser without foreground activity", null)return}val intent = Intent(Intent.ACTION_VIEW)intent.data = http://www.srcmini.com/Uri.parse(url)activity!!.startActivity(intent)result.success(true as Any) } companion object {private val CHANNEL ="flutterplugins.srcmini.com/browser" }}
在MainActivity.kt文件中, 我们创建了一个openBrowser()方法来打开浏览器。
private fun openBrowser(call:MethodCall, result:Result, url:String?) {val activity = thisif (activity == null){result.error("UNAVAILABLE", "It cannot open the browser without foreground activity", null)return}val intent = Intent(Intent.ACTION_VIEW)intent.data = http://www.srcmini.com/Uri.parse(url)activity!!.startActivity(intent)result.success(true as Any) }
输出量
【Flutter创建特定于Android平台的代码】现在, 在你的android studio中运行该应用程序, 你将获得以下输出。当你单击按钮Click Here时, 你可以看到浏览器主页屏幕已启动。
文章图片
文章图片
推荐阅读
- Flutter导航和路由
- Flutter动画
- Flutter列表
- Flutter抽屉drawer
- Flutter标签栏
- Flutter图像
- Flutter警报对话框
- Flutter表单
- Flutter状态管理