📅  最后修改于: 2020-12-08 04:43:56             🧑  作者: Mango
Flutter提供了访问平台特定功能的通用框架。这使开发人员可以使用平台特定的代码扩展Flutter框架的功能。可以通过框架轻松访问特定于平台的功能,例如摄像头,电池电量,浏览器等。
访问平台特定代码的总体思路是通过简单的消息传递协议。 Flutter代码,客户端和平台代码以及主机绑定到公共消息通道。客户端通过消息通道向主机发送消息。主机在消息通道上侦听,接收消息并执行必要的功能,最后,通过消息通道将结果返回给客户端。
特定于平台的代码架构如下面的框图所示-
消息传递协议使用标准消息编解码器(StandardMessageCodec类),该编解码器支持类似JSON的值(例如数字,字符串,布尔值等)的二进制序列化。序列化和反序列化在客户端和主机之间透明地工作。
让我们编写一个简单的应用程序以使用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。
现在,导入以下软件包-
import 'dart:async';
import 'package:flutter/services.dart';
在这里,services.dart包含调用平台特定代码的功能。
在MyHomePage小部件中创建一个新的消息通道。
static const platform = const
MethodChannel('flutterapp.tutorialspoint.com/browser');
编写一个方法_openBrowser通过消息通道调用特定于平台的方法openBrowser方法。
Future _openBrowser() async {
try {
final int result = await platform.invokeMethod(
'openBrowser', {
'url': "https://flutter.dev"
}
);
}
on PlatformException catch (e) {
// Unable to open the browser
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.tutorialspoint.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.tutorialspoint.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.tutorialspoint.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);
}
}
主镖
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.tutorialspoint.com/browser');
Future _openBrowser() async {
try {
final int result = await platform.invokeMethod('openBrowser', {
'url': "https://flutter.dev"
});
}
on PlatformException catch (e) {
// Unable to open the browser print(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.title),
),
body: Center(
child: RaisedButton(
child: Text('Open Browser'),
onPressed: _openBrowser,
),
),
);
}
}
运行该应用程序,然后单击“打开浏览器”按钮,您可以看到浏览器已启动。浏览器应用程序-主页如此处的屏幕截图所示-