最近测验将平板程序编译成web运用发布,发布后程序能够运转,可是存在一些问题。现将问题和处理进程记录如下
-
web运用加载耗时问题
- 加载时会去www.gstaic.com下载/chromium/canvaskit.js文件和canvaskit.wasm文件,
- 加载时会去www.gstaic.com下载notosanssc字体文件和roboto字体
打包指令
我的打包指令为:
flutter build web -t lib/main.dart --no-tree-shake-icons --release
处理下载字体的问题
-
将需求下载的资源文件预下载放入项目中
- 从对应的字体网址下载好roboto.ttf和notosanssc.otf
- 将字体文件放在项目中的资源文件中
- 在项目的ymal文件中加入Font声明
- 打包项目,打包后build文件如下
运转测验发现roboto.ttf文件现已能够从资源中下载,可是notosanssc.otf任然会从gstaic.com下载
-
处理notosanssc.otf依然需求下载的问题
- 修该ymal中Roboto字体的资源文件为notosanssc.otf
- 打包测验
- 不会再从gstaic中下载文件。这个办法不清楚原因,有知道原因的欢迎谈论指正
-
处理canvaskit.js文件和canvaskit.wasm问题
- buil目录中发现存在canvaskit.js和canvaskit文件
-
修改–dart-define=FLUTTER_WEB_CANVASKIT_URL为:canvaskit/,即
- –dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/
-
此刻编译指令为:
-
flutter build web -t lib/main.dart --no-tree-shake-icons --release --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/
-
-
测验
-
chrome和safari加载时间不一致的问题
-
canvaskit.wasm这个文件在chrome中需求耗时16s,在safari只是需求60ms
-
chrome
-
-
safari
-
这个问题也不清楚原因,暂时未处理
-
参考:我把FlutterWeb烘托模式改成Canvaskit后… – 掘金
-
web浏览器刷新,url会重置的问题
我的项目是一个插件项目,需求主程序经过url传入一个资源地址,然后插件项目读取地址栏的地址,去下载并加载对应文件。首要代码如下:
void main() async {
String? assetsApi = Uri.base.queryParameters['assetsApi'];
printDebug("wbeApp start assetsApi:$assetsApi");
runApp(MyApp(interface: MyControl(assetsApi: assetsApi ?? "")));
}
Widget build(BuildContext context) {
return GetMaterialApp(
home: AppUI(
interface: interface,
) ,
);
}
- 此刻debug直接运转:http://localhost:51335/#/
- 修改地址运转:http://localhost:51335/?assetsApi=http://172.16.132.147:5000/api/roomConfig/downloadAppUIAssets?roomId=tAnHi86sRdsFbTzF4
此刻程序能够读取地址栏的url,并正确加载
-
可是加载完成后,无法记录我们输入的url地址栏url再次变为:http://localhost:51335/#/
-
处理办法
- 运用setUrlStrategy办法
-
import 'package:flutter_web_plugins/flutter_web_plugins.dart'; void main() async { String? assetsApi = Uri.base.queryParameters['assetsApi']; printDebug("wbeApp start assetsApi:$assetsApi"); setUrlStrategy(PathUrlStrategy()); runApp(MyApp(interface: MyControl(assetsApi: assetsApi ?? ""))); }
- 对app增加router
-
Widget build(BuildContext context) { String basePath = Uri.base.path; debugPrint("basePath:$basePath"); String router = "/?assetsApi=${interface.url}"; debugPrint("router:$router"); return GetMaterialApp( initialRoute: router, routes: { router: (_) { return AppUI( interface: interface, ); } }, onGenerateRoute: (settings) { debugPrint('onGenerateRoute name: ${settings.name}'); }, onUnknownRoute: (settings){ debugPrint('onUnknownRoute name: ${settings.name}'); }, // home: AppUI( // interface: interface, // ) , ); } }
- 此刻从url加载完成程序后,地址栏不会重置,会记住上次的目录
- initialRoute的值不知道怎么填写的时分,能够从onUnknownRoute或许onGenerateRoute中寻找
-
dart.io和dart:js
web项目中运用dart.io库中的API时会反常报错
非web项目无法运用dart:js的API时也会反常
那怎么在一个功能中经过渠道判别来运用不同的API呢
-
怎么在同一个项目中同时运用dart.io和dart.js两个库的
操作如下:
- 界说接口类abstract class,运用import if 来做头文件导入判别
import 'desktop_mobile.dart'
if (dart.library.html) 'web.dart';
abstract class App{
Future<Map> init();
factory App() => getApp();
}
-
完成非web接口类
-
import 'dart:convert'; import 'package:flutter/services.dart'; import 'app.dart'; class MobileApp implements App { @override Future<Map> init() async { String data = await rootBundle.loadString("assets/project_json.json"); Map jsonData = jsonDecode(data); return jsonData; } } App getApp() => MobileApp();
-
-
完成web接口类
- 从js传过来的json格式数据可能导致dart无法辨认,所以改为传jsonString
import 'dart:convert';
import 'package:flutter/services.dart';
import 'app.dart';
import 'dart:js' as js;
class WebApp implements App {
@override
Future<Map> init() async {
String? jsonString = js.context["appConfig"];
jsonString ??= await rootBundle.loadString("assets/project_json.json");
return jsonDecode(jsonString);
}
}
App getApp() => WebApp();
- 运用
import 'app/app.dart';
Map jsonData = await App().init();
-
runtimeType在web和手机端不同
web渠道下数据的runtimeType和非原生不一样,判别数据类型时最好用is关键字来判别
如:
dynamic values = json[key];
if (values != null && values is Map) {
}
而不运用
dynamic values = json[key];
if (values != null && values.runtimeType.toString().contains("Map")) {
}
以下是部分整理
-
macos渠道
// int
dynamic int1 = 1; // int
int int2 = 1; // int
// double
dynamic double1 = 1.0; // double
double double2 = 1.0; // double
// number
dynamic num1 = 2; // int
dynamic num2 = 2.0; // double
num num3 = 2; // int
num num4 = 2.0; // double
// string
dynamic string1 = "1.0"; // String
String string2 = "1.0"; // String
// map
dynamic map1 = {"1":2};// _Map<String, int>
dynamic map2 = {"1":2,"2":"2"};// _Map<String, Object>
dynamic map3 = {"1":2,"2":"2",1:'2'};// _Map<Object, Object>
Map map4 = {"1":2}; // _Map<dynamic, dynamic>
Map<dynamic,dynamic> map5 = {"1":2}; // _Map<dynamic, dynamic>
Map<String,dynamic> map6 = {"1":2}; // _Map<String, dynamic>
Map<dynamic,String> map7 = {"1":"2"};// _Map<dynamic, String>
// list
dynamic list1 = [1,2];// List<int>
dynamic list2 = ["1",2];// List<Object>
dynamic list3 = [1,2,{}];// List<Object>
List list4 = [{"1":2},{"1":2,"2":"2"}];// List<dynamic>
-
web渠道
// int
dynamic int1 = 1; // int
int int2 = 1; // int
// double
dynamic double1 = 1.0; // int
double double2 = 1.0; // int
// number
dynamic num1 = 2; // int
dynamic num2 = 2.0; // int
num num3 = 2; // int
num num4 = 2.0; // int
// string
dynamic string1 = "1.0"; // String
String string2 = "1.0"; // String
// map
dynamic map1 = {"1":2};// IdentityMap<String, int>
dynamic map2 = {"1":2,"2":"2"};// IdentityMap<String, Object>
dynamic map3 = {"1":2,"2":"2",1:'2'};// LinkedMap<Object, Object>
Map map4 = {"1":2}; // LinkedMap<dynamic, dynamic>
Map<dynamic,dynamic> map5 = {"1":2}; // LinkedMap<dynamic, dynamic>
Map<String,dynamic> map6 = {"1":2}; // IdentityMap<String, dynamic>
Map<dynamic,String> map7 = {"1":"2"};// LinkedMap<dynamic, String>
// list
dynamic list1 = [1,2];// List<int>
dynamic list2 = ["1",2];// List<Object>
dynamic list3 = [1,2,{}];// List<Object>
List list4 = [{"1":2},{"1":2,"2":"2"}];// List<dynamic>
-
Flutter web嵌入web项目
Flutter build的产品作为一个静态资源放在web项目中,web项目想调到flutter页面中,运用window.open函数
window.open(URL,name,specs,replace)