Dro*_*dOS 6 android webview ios cordova flutter
我在 Android 上有一个非常复杂的 Cordova 应用程序,我已经开发了一年多的时间。该应用程序使用一种自定义方式,即由我编写的 Cordova 插件。AI 考虑将应用程序移植到 iOS 我正在考虑切换到 Flutter 以便只维护一个代码库 - 如果整个插件将不得不为 iOS 重写。
使用干净的 HTML5 + ES6 + CSS3,它运行得非常好,我认为没有理由把它全部扔掉,重新作为一个纯 Flutter 应用程序重新开始。输入 Web 视图。我计划在颤动的 WebView 中使用我当前的所有 Cordova Webview 代码 - 基本上是整个 Cordova 项目 www 文件夹。这一切的关键是能够在 WebView 和 Flutter 之间有效地进行双向通信。为此,我编写了一个小型骨架项目。该main.dart项目的文件如下所示
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:convert';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(Webby());
class Webby extends StatelessWidget
{
@override Widget build(BuildContext context)
{
return MaterialApp
(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue,),
home: Feuille(),
);
}
}
class Feuille extends StatefulWidget
{
Feuille({Key key}):super(key: key);
@override _FeuilleState createState() => _FeuilleState();
}
class _FeuilleState extends State<Feuille>
{
WebViewController wVC;
@override Widget build(BuildContext context)
{
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
return Scaffold
(
body:SafeArea
(
child:Column
(
children:<Widget>
[
Expanded
(
child:Container
(
margin:const EdgeInsets.all(0.0),
child:WebView
(
debuggingEnabled:true,
initialUrl:'',
javascriptMode:JavascriptMode.unrestricted,
onWebViewCreated:registerController,
javascriptChannels:Set.from
([JavascriptChannel(name:'JSBridge',onMessageReceived:handleMessage)]),
),),)])));
}
Future<void> handleMessage(JavascriptMessage message) async
{
print(message.message);
wVC.evaluateJavascript("addNums(10,21)");
}
void registerController (WebViewController controller) async
{
wVC = controller;
String html = await rootBundle.loadString('assets/index.html');
wVC.loadUrl(Uri.dataFromString(html,mimeType:'text/html',
encoding:Encoding.getByName('utf-8')).toString());
}
}
Run Code Online (Sandbox Code Playgroud)
加载到此 webview 中的本地 HTML 如下所示
<!DOCTYPE html>
<html>
<head>
<meta name='viewport'
content='user-scalable=no, initial-scale=1, maximum-scale=1,
minimum-scale=1, width=device-width, height=device-height' />
<meta charset='utf-8' />
</head>
<body>
<p>The result is <span id="spnResult">Not Available Yet</span></p>
</body>
<script>
window.addEventListener("load",flutterReady);
function flutterReady()
{
alert("Sending message");
setTimeout(function(){JSBridge.postMessage("This is London calling");},5000);
}
function addNums(n1,n2)
{
document.getElementById("spnResult").innerText = n1 + n2;
}
</script>
</html>
Run Code Online (Sandbox Code Playgroud)
最后pubspec.yaml项目的文件如下
name: webby
description: Webby Project
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
path_provider: ^1.4.0
permission_handler: ^3.3.0
connectivity: ^0.4.5+6
webview_flutter: ^0.3.19+9
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets:
- assets/
Run Code Online (Sandbox Code Playgroud)
现在我的问题
我正在使用这个骨架项目来测试我是否可以双向通信:从 Webview 托管的 JS 到 Flutter,从 Flutter 返回到 Webview 托管的 JS。这有效 - 非常好。然而,我在这里做了一些非常盲目的事情——这是我使用 Flutter 的第二天——需要澄清
我已经使用 HTML5 中的 window.load 事件来了解我何时开始与 Flutter 通信。这是我对 Cordova.docReady 事件的替代。假设发生此事件时 Flutter 将“准备好”,WebViewController 将可用等是否合理?
在我努力让 WebView 占据整个设备屏幕的过程中,我最终使用的Scaffold...SafeAera...Expanded...很简单,因为我遇到了它被用来显示全屏图像并且它对我有用。但是,我不清楚这是做事的最佳方式/正确方式
我注意到pubspec.yaml指定使用 Material Design 和这里创建的“小部件”是一个MaterialApp. 鉴于我的整个 UI 是通过 WebView 中的 HTML5 + CSS3 + ES6 创建和管理的,没有一种更简单的方法来创建可能带来一些性能/内存占用优势的小部件
我遇到过这样的评论,即 WebView 很慢,在 iOS 上不能很好地呈现等等。根据我的经验,发表此类评论的人通常倾向于依赖“框架”,这会给系统带来不必要的负担。干净的 HTML + ES6 仅依赖于 HTML5 DOM 作为其“框架”性能对我来说从来都不是问题。Flutter WebView(最终是操作系统提供的 WebView)表现不佳是否有任何已知原因?
最后:一旦我确定了这一点,我就需要开始实施地理定位、Wifi 网络监视、加速度计监控、websocket 驱动的 I/O、本地文件存储、SQLite 数据库存储等。Fluter 提供的 API 是否适合这些任务 -他们是否充分了解操作系统,才能真正为 Android 和 iOS 生成应用程序?
我将非常感谢任何能够在这里提供一些提示和指示的人。
我不确定我会在这里得到回应。但是,对于遇到此线程并试图复制我迄今为止所做的任何人的人来说,这是一个脚注。
很简单——这行不通。使用Uri.dataFromString(...将允许您显示带有嵌入样式和 JS 的静态 HTML 文档。它将无法访问存储在 Flutterassets文件夹内其他文件/文件夹中的样式表和脚本。为此,您需要运行本地 HTTP 服务器。虽然您可以尝试自己旋转,但不值得这样做。考虑使用优秀的、有据可查的 flutter_inappwebview插件。
据我了解,您似乎只想在 Flutter 上使用 WebView 显示网页。如果您需要访问 WebView 上的地理定位支持,webview_flutter 仍然存在此问题。作为解决方法,您可能需要考虑同时使用flutter_inappwebview 。至于在 Flutter 上处理 WebView 回调,这里有一个有趣的指南,您可以将其作为开始。
| 归档时间: |
|
| 查看次数: |
1424 次 |
| 最近记录: |