花千醉

文能上马定乾坤,武能提笔安天下!

0%

Flutter 踩坑一览

安装 + 编译 部分

编译 Linux 时报错、

太坑了,忙活了好几个小时,终于解决了

两种表现形式

1
2
3
4

/usr/bin/ld: cannot find -lstdc++
/usr/include/glib-2.0/glib/glib-typeof.h:39:10: fatal error: 'type_traits' file not found

不能在 /usr/lib/x86_64-linux-gnu/ 直接链接 libstdc++.6.solibstdc++,这样会报错

这个网页给出的方法行不通,反而干扰 浅醉 的后续排错。
ubuntu “/usr/bin/ld文件夹:找不到-lstdc++:运行flutter linux应用程序时没有这样的文件或目录” _大数据知识库

解决办法:

1
sudo apt install libstdc++-12-dev 

其他包行不行,没有试。

https://stackoverflow.com/questions/33193667/clang-version-3-8-0-clang-type-traits-file-not-found

https://packages.debian.org/search?searchon=contents&keywords=%2Ftype_traits&mode=&suite=bullseye&arch=any

这问题很隐晦,错误检测:

对于以下文件

1
2
3
4
5
6
#include <type_traits> 

int main()
{
return 0 ;
}

尝试编译

1
2
3
4
5
6
7

# Error!!! clang 11 to 14
clang++ main.cc

# But g++ is OK!
g++ main.cc

再编译一下,Flutter 构建成功

调试网页端(其他浏览器)Web Debug

平时不太用的惯 Chrome,目标群体也少有 Chrome 党,Web 端要测试 Firefox 和 Safai。

如果直接 flutter run,在 Linux 下,只会编译 Linux Desktop,如果用 flutter run -d chrome ,想都不用想,直接找不到 Chrome,提示输入 Chrome 路径,

网络上转一圈,倒是有程序猿在 flutter 的 issue 里面直接提 Support Firefox as a browser in flutter run #55324 ,当然,官方根本没有理睬 —— Google 的气度只够保持 issue open(狗头)。

不过,StackOverflow 上倒有靠谱的方案,参考 Add firefox as device when running flutter web

1
2
3
4
5
6
7
8
9
10
11
12
13
14

flutter run -d web-server # --web-port=xxxx --release

# output like:
Launching lib/main.dart on Web Server in release mode...
Compiling lib/main.dart for the Web... 13.5s
lib/main.dart is being served at http://localhost:8888
The web-server device requires the Dart Debug Chrome extension for debugging. Consider using the Chrome or Edge devices for an improved development workflow.

🔥 To hot restart changes while running, press "r" or "R".
For a more detailed help message, press "h". To quit, press "q".

# 哇哦!在下 终端里面还没看到 这个 🔥 呢!

然后在 Firefox 上就可以愉快的访问了

日常运用部分

1. JSON序列化

1. Dio

注意,序列化直接使用 resp.toString() 即可。使用 resp.data.toString() 反而会报错。

1
2
3
4
5
6
7
8
9

flutter: FormatException: Unexpected character (at character 2)

# 或者
flutter: NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'call'.

Receiver: _LinkedHashMap len:2

Tried calling: call()

正确示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Future<String> getHttp() async
{
try {
Dio d = Dio();
Response resp = await d.get("http://localhost:1234");
//var user = jsonDecode(resp.data.toString());
var user = jsonDecode(resp.toString());
print(user);
return "OK";
}
catch(e)
{
print(e);
print("Error");
return "Bad";
}
}

2. JSON列表

这段Flutter代码无法正确接收像这样的数据,是因为它假定服务器返回的数据是一个JSON对象,但实际上返回的是一个JSON数组。在以下代码中,response.data是一个JSON数组:

1
2
3
4
5
6
int len = response.data.length; 
List<Map<String, dynamic>> info = [];
for (var i = 0; i < len; i++ ) {
Map<String, dynamic> tmp = jsonDecode(response.data[i].toString());
info.add(tmp);
}`

为了正确接收返回的数据,需要将以下代码:
Map<String, dynamic> tmp = jsonDecode(response.data[i].toString());
改为:
Map<String, dynamic> tmp = response.data[i];
这样,就可以正确地将返回的JSON数组转换为一个包含多个JSON对象的List了。

2. 路由传递

这里面弯弯道道太多了,

1. stateless widget: Undefined name ‘context’.

Navigator 部分报错是因为在 DicTableBody 中调用了 Navigator.push 方法,但是该方法需要 context,但是 DicTableBody 是一个无状态组件,没有直接的 context 可以使用。解决方法是将 context 传递给 DicTableBody 的构造函数,然后在调用 Navigator.push 方法时使用该 context。

具体解决方法是在 DicTableBody 类中增加一个成员变量 _context,然后在构造函数中传递 context 参数并保存到 _context 成员变量中。最后在调用 Navigator.push 方法时使用 _context。

3. 打包部署

Flutter底层是C++,现在谁用自己的小本子打包呀。Gay Hub Action 走起来。

请参考:https://github.com/flutter/gallery/tree/main/.github/workflows 尤其是文件 build.yml 和 release_draft_github_release.yml