Flutter提供了访问平台特定函数的通用框架,这使开发人员可以使用平台特定的代码扩展 Flutter 框架的函数,可以通过框架轻松访问平台特定的函数,例如相机,电池电量,浏览器等。
访问平台特定代码的总体思路是通过简单的消息传递协议,Flutter代码,客户端和平台代码以及主机绑定到公共消息通道。客户端通过消息通道向主机发送消息。主机在消息通道上侦听,接收消息并执行必要的函数,最后通过消息通道将输出返回给客户端。
特定于平台的代码架构显示在下面的框图中-
消息传递协议使用标准消息编解码器(StandardMessageCodec类),该消息编解码器支持类似JSON的值(例如数字,字符串,布尔值等)的二进制序列化。序列化和反序列化在客户端和主机之间工作。
下表显示了如何在Android和iOS平台上接收Dart值
dart | android | ios |
---|---|---|
null | null | 无(嵌套时为NSNull) |
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 |
让无涯教程编写一个简单的应用程序,以使用 Android SDK 打开浏览器,并了解如何
在Android Studio中创建新的Flutter应用程序, flutter_browser_app
将main.dart代码替换为以下代码-
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(this.title), ), body: Center( child: RaisedButton( child: Text('Open Browser'), onPressed: null, ), ), ); } }
在这里,无涯教程创建了一个新按钮来打开浏览器并将其onPressed方法设置为null。
现在,导入以下软件包-
链接:https://www.learnfk.comhttps://www.learnfk.com/flutter/flutter-writing-andriod-specific-code.html
来源:LearnFk无涯教程网
import 'dart:async'; import 'package:flutter/services.dart';
在这里,services.dart包含了调用平台特定代码的函数。
在MyHomePage Widget中创建一个新的消息通道。
static const platform = const MethodChannel('flutterapp.learnfk.com/browser');
编写一个方法_openBrowser通过消息通道调用特定于平台的方法openBrowser方法。
Future<void> _openBrowser() async { try { final int result = await platform.invokeMethod( 'openBrowser', <String, String>{ 'url': "https://flutter.dev" } ); } on PlatformException catch (e) { //无法打开浏览器 print(e); } }
在这里,无涯教程使用platform.invokeMethod调用openBrowser(在后续步骤中进行了说明)。 openBrowser有一个参数,URL以打开特定的URL。
将RaisedButton的onPressed属性的值从null更改为_openBrowser。
onPressed: _openBrowser,
打开MainActivity.java(在android文件夹内)并导入所需的库-
import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import io.flutter.app.FlutterActivity; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.GeneratedPluginRegistrant;
写一个方法,openBrowser打开浏览器
private void openBrowser(MethodCall call, Result result, String url) { Activity activity = this; if (activity == null) { result.error("ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without foreground activity", null); return; } Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); activity.startActivity(intent); result.success((Object) true); }
现在,在MainActivity类中设置频道名称-
private static final String CHANNEL="flutterapp.learnfk.com/browser";
编写Android特定代码以在onCreate方法中设置消息处理-
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( new MethodCallHandler() { @Override public void onMethodCall(MethodCall call, Result result) { String url = call.argument("url"); if (call.method.equals("openBrowser")) { openBrowser(call, result, url); } else { result.notImplemented(); } } });
在这里,无涯教程使用MethodChannel类创建了一个消息通道,并使用MethodCallHandler类来处理消息,onMethodCall是负责通过检查消息来调用正确的平台特定代码的实际方法。 onMethodCall方法从消息中提取URL,然后仅在方法调用为openBrowser时才调用openBrowser。否则,它返回notImplemented方法。
该应用程序的完整源代码如下-
MainActivity.java
package com.learnfk.flutterapp.flutter_browser_app; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import io.flutter.app.FlutterActivity; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { private static final String CHANNEL = "flutterapp.learnfk.com/browser"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( new MethodCallHandler() { @Override public void onMethodCall(MethodCall call, Result result) { String url = call.argument("url"); if (call.method.equals("openBrowser")) { openBrowser(call, result, url); } else { result.notImplemented(); } } } ); } private void openBrowser(MethodCall call, Result result, String url) { Activity activity = this; if (activity == null) { result.error( "ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without foreground activity", null ); return; } Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); activity.startActivity(intent); result.success((Object) true); } }
main.dart
import 'package:flutter/material.dart'; import 'dart:async'; import 'package:flutter/services.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage( title: 'Flutter Demo Home Page' ), ); } } class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; static const platform = const MethodChannel('flutterapp.learnfk.com/browser'); Future<void> _openBrowser() async { try { final int result = await platform.invokeMethod('openBrowser', <String, String>{ 'url': "https://flutter.dev" }); } on PlatformException catch (e) { //无法打开浏览器打印(e); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(this.title), ), body: Center( child: RaisedButton( child: Text('Open Browser'), onPressed: _openBrowser, ), ), ); } }
运行该应用程序,然后单击"打开浏览器"按钮,您可以看到浏览器已启动。浏览器应用程序-主页如此处的屏幕截图所示-
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)