flutter 编写 android 特定代码——迹忆客-ag捕鱼王app官网
flutter 提供了一个通用框架来访问平台特定的功能。 这使开发人员能够使用特定于平台的代码来扩展 flutter 框架的功能。 可以通过框架轻松访问特定于平台的功能,如相机、电池电量、浏览器等。
访问平台特定代码的总体思路是通过简单的消息传递协议。 flutter 代码、client 和平台代码以及 host 绑定到一个通用的 message channel。 客户端通过消息通道向主机发送消息。 主机监听消息通道,接收消息并执行必要的功能,最后通过消息通道将结果返回给客户端。
特定于平台的代码架构如下面的框图所示
消息传递协议使用标准消息编解码器(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.jiyik.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); } }
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.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, ), ), ); } }
运行应用程序并单击 open browser 按钮,我们可以看到浏览器已启动。浏览器应用程序 - ag捕鱼王app官网主页如这里的屏幕截图所示