前言: 很久没更新文章了, 做个更新; 前段时间, 8 9 月份在接触 ml kit, 机器学习, tensorflow 相关的(比较耗时间, 而且基本上都是皮毛); 由于后面一段时间工作上实在是太忙就断掉了; 然后这个月有时间开始搞搞 flutter, 后面倒是想试试 tensorflow lite, 就是不知道有没有时间和动力;
这篇主要介绍作为一个 Android developer 最近这段时间使用 flutter(比较初级)的一些感受吧, 具体的技术细节准备好了, 后面的文章会慢慢分功能模块整理出来.
作为一个 Android 程序员, 学点其他相关的很正常; 比如 web 前端也懂一点, 后端也懂一点. 但是学一个东西肯定不是脑袋一热就去搞, 什么都去搞搞, 哪有那么多时间. 毕竟上班拿工资就要写 Android 业务的, 一周也就下班回来 2,3 个小时和周末是自由的, 还要去掉减压的时间.
所以为什么会去学 flutter 呢?
flutter 优势:
1. 跨平台
提起 flutter, 最先谈的就是它的跨平台咯.
用 dart 语言编写, 一套代码在 Android,iOS 上运行. 相比于 RN 页面由前端写, flutter 则是以一种新的形势出现, 独立于 Android,iOS,Web; 这样的好处是, 前端也不会 flutter, 大家基本都在同一起跑线(个人感觉);
当 demo 在两个模拟器上都跑起来的时候还是很开心的, 哈哈.
如果后面 Fuchsia 出来了, 可以跨 Fuchsia 就更牛逼了.
2. 性能和开发相关
flutter 号称每秒 60 帧, 性能上是媲美甚至是超过原生开发的;
这点因为我写的都是小 demo, 所以感觉不到快慢. GitHub 上 clone 别人的几个大一点的项目, 跑出来效果基本上感觉不出是 flutter 写的, 和原生的差不多;
关于热部署这点, 其实算是和 Android 的 instant run 类似. 但是好像要快一些, 比如改一下 home 里面的一些 widget 状态, 热部署后秒更新 ui, 瞬间看到代码修改后的结果, 还是挺猛的. 大大提高了开发效率. 不过就是有 bug 了, 这个后面缺点再说.
上手后开发 App 还是挺快的. 因为不管用什么开发, 最后出来的 App 肯定是要和产品想要的一样. 所以, 熟悉了基本 flutter 开发流程后, Android developer 使用 flutter 开发 App 流程还是和原生大同小异的. iOS 不太清楚, 但是听一个 iOS 开发说, flutter 语法以及开发特点上更像 oc. 不过 Android 开发者比 iOS 开发者的最明显的优势就是 flutter 支持 androidStuido, 却不支持 xCode.
flutter 内置了很多东西. 比如一些小控件图片资源, 网络图片缓存啥的, 用起来很方便.
dart 语言特性. 写 list 等数据结构, 还有类似 builder 构造函数用起来挺爽的.
3.flutter 和 google 的关系
这段时间大家都应该听说 google 和甲骨文公司的纠纷, 以及前段时间欧盟 Android 收费等消息.
Android 从 java 到提供 kotlin 开发, 然后到现在 flutter 的出现.
然后就是新的 google Fuchsia 系统(统一 Android 和 Chrome os), 也是用 dart 语言开发, 不确定是不是 flutter. 如果后面这个新的系统真的出来, 并且可以在手机上跑, 那么到时候移动端很可能是 Android iOS Fuchsia 三分天下了.
这里就有问题了(以下只是个人见解, 以及一些危机意识):
现在每个公司除了跨平台, 都有 Android,iOS 独立的开发小组, 那么 Fuchsia 出来后呢? 三个小组? 然后发现 flutter 写的在三个系统都可以跑, 那还有必要开三份工资吗?
或者说会保留一些原生开发, 可能一些功能跨平台做不了, 还是要每个原生系统自己去实现(模块的方式). 但是大部分还是跨平台去实现了. 如果真是这样, 那么如果只会 Android 或者只会 iOS, 到时候说不定真的会凉凉, 难受啊马飞.
但是这也算是一个机会吧, 如果 Fuchsia 真的火起来了, 一些大厂或者针对海外市场的公司应该会去占领这个新的操作系统的市场. 到时候只有小部分开发者会 flutter, 而你刚好在其中(熟练 & 精通), 岂不是美滋滋.
4. 其他实际一点的
今年 GDD, 闲鱼真是出彩, 除了 tensorflow lite 的应用, flutter 的应用也是超级厉害, 感觉真是业界的领头羊. 闲鱼的部分务模块已经用 fluuter 接到原来的框架了, 并且经受住了千万, 亿级别的考验; 说明这东西还是靠谱的. 之前还看到知乎上的闲鱼技术官方号在招 flutter 开发, 牛逼的可以去试一下.
现在一些公司的 Android 招聘要求, 已经把 flutter 作为和 rn,weex 一样的加分项了.
如果之前你没有系统的通过官方文档学习(比如学 Android,java 是通过别人整理的资料: 书籍, 博客, 视频等), 可以用 flutter 中文网 https://flutterchina.club/ 来练练手. 英语过关的可以直接看英文版的. 官方文档才是第一手资料, 看别人整理过的东西, 别人已经帮你踩过坑, 思考过了, 而且可能还表达的不全面.
大部分人都想成为垦荒者吧, 互联网技术这块还是国外的先进一些. 如果是一项新技术, 应该是英文文档先出来, 等整理成中文网站就慢一步了. 如果再等国内大佬发博客, 出书籍就更慢了.
flutter 的缺点:
说说个人最近使用 flutter 后对 flutter 的一些吐槽吧
1. flutter 的包体积比原生开发的大
会比 Android 原生 apk 大一些. 因为渲染引擎放到了 App 里面.
image.PNG
image.PNG
下面是 apk(别人 GitHub 上的项目, 业务较少)体积:
image.PNG
(到目前由于经验较少, 不确定业务量增大后, apk 大小增长的速度是不是和原生的一致了. 如果本来 apk 就有 50 多 M,flutter 引擎如果只是增加 7M, 一共 60M, 貌似也可以接受)
至于为什么要把引擎放到 App 里面, 现在我也不懂. google 了一下, 看有人说应用程序中包含 C / C ++ 引擎和 Dart VM 是为了应用程序直接使用本机指令集运行, 不涉及任何解释器.
2.flutter 的 ui 刷新问题
每次重新绘制那一下, 特别是列表滑动, Android 上稍微认真观察, 就会发现会卡一下. iOS 不明显, Android 比较明显. 闲鱼的详情页也有这种情况.
flutter ui 的概念是 every thing is widget, 就连页面也是一个 widget.widget 又分有状态和无状态.
个人觉得吧, 无状态的 widget 就是为了让 Ui 不要重新绘制.
猜测原因 (没看过 flutter 的 CPU proflier, 纯属瞎 BB):list 滑动刷新通过有状态 widegt 来刷新状态(setState) 来重新绘制页面造成的瞬间卡顿.
3.flutter 是用代码布局, 没有 xml 的概念, 对 Android 程序员不太友好
(demo 是 Stack Overflow 上的一个 flutter 使用相对布局的回答, 然后答得太好直接被官网引用了, 牛逼啊)
可能 iOS 开发要好适应一些, 但是 Android 开发习惯了 xml 布局, 刚开始接触可能不太适应(使用一阵子就习惯了).
Android 里面看 Ui 布局, 一般是通过 xml 来看大概的布局, 虽然有时也会用代码动态管理 ui, 不过大部分还是习惯用 xml 布局.
比如下图:
flutter 的布局是一层套一层, 如果要使用复杂一点的布局, 就得嵌套多层. 下面的布局是 list 的一个小 item.
- class Song extends StatelessWidget {
- const Song({this.title, this.author, this.likes});
- final String title;
- final String author;
- final int likes;
- @override
- Widget build(BuildContext context) {
- TextTheme textTheme = Theme.of(context).textTheme;
- return new Container(
- margin: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 5.0),
- padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 0),
- decoration: new BoxDecoration(
- color: Colors.grey.shade200.withOpacity(0.3),
- borderRadius: new BorderRadius.circular(5.0),
- ),
- child: new IntrinsicHeight(
- child: new Row(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: <Widget>[
- new Container(
- margin: const EdgeInsets.only(
- left: 0, top: 4.0, bottom: 4.0, right: 10.0),
- child: new CircleAvatar(
- backgroundImage: new NetworkImage(
- 'http://thecatapi.com/api/images/get?format=src'
- '&size=small&type=jpg#${title.hashCode}'),
- radius: 20.0,
- ),
- ),
- new Expanded(
- child: new Container(
- child: new Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: <Widget>[
- new Text(title, style: textTheme.subhead),
- new Text(author, style: textTheme.caption),
- ],
- ),
- ),
- ),
- new Container(
- margin: new EdgeInsets.symmetric(horizontal: 5.0),
- child: new InkWell(
- child: new Icon(Icons.play_arrow, size: 40.0),
- onTap: () {
- // TODO(implement)
- },
- ),
- ),
- new Container(
- margin: new EdgeInsets.symmetric(horizontal: 5.0),
- child: new InkWell(
- child: new Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: <Widget>[
- new Icon(Icons.favorite, size: 25.0),
- new Text('${likes ??''}'),
- ],
- ),
- onTap: () {
- // TODO(implement)
- },
- ),
- ),
- ],
- ),
- ),
- );
- }
- }
image.PNG
刚开始是会觉得这个好麻烦, 代码里面利用 row 包 children,children 里面有 clumn 包 children, 就像一颗 ui 结构树一样, 然后每个树节点用类似 builder 模式传一些参数进去描述具体节点特征.(下图是官网上另一个 demo 的例子, 直接 copy 过来示意一下, 和这个 demo 不对应)
image.PNG
好消息是可能是因为 dart 和 flutter 的机制, 虽然没有 xml 看 ui 结构, 但是可以通过代码旁的结构树来查看. 点击树里面的节点还能对应到具体的代码位置. 还是挺不错的.
image.PNG
4.flutter 有 bug
热部署有时候有问题
虽然 flutter 的热部署很厉害, 很好用, 但是也有熄火的时候.
一种情况:
如果你的 App 是多个页面, 如果当前页面在 c, 但是你改了其他页面的代码想看效果, 这时候热部署完了之后还是在 c 页面的; 你想看到其他页面修改后的效果, 需要手动切到那个页面. 这个可能跟 flutter 的一个页面也是属于 widget 有关. 当然如果重新运行, 他还是会从 main 函数入口开始重新执行初始化逻辑.
另外一种情况:
上面那种情况其实还可以接受. 但是有时候热部署会突然卡住, 然后一直卡在同步数据中, 一般卡好一会儿. 这时候因为在等待执行 hot reload, 所以也点击不了重新运行.
image.PNG
等一会就变成这个样子, 然后就 GG 了, 必须得重新关掉 ide 再打开...
flutter sdk 会突然抽风
flutter 有类似 Android gradle 的管理叫 pubspec.YAML
image.PNG
有时不小心点到 flutter 升级后, 升级完就 GG 了. 不知道是不是操作不当, 然后之前能跑的项目就跑不了了. 更正 flutter doctor 尝试也不行, 最后只好把 flutter sdk,flutter plugin,dart plugin 全部清掉, 又重新装一遍.
最奇怪的一次是昨天晚上还跑的好好地, 今天白天去公司用 androidStuido 写 Android 项目, 完全没动 flutter 相关的东西, 晚上回来就跑不了 flutter 项目了. 各种查, 找不到原因, 又重新装了一次.
我每次都是用的 GitHub 上 flutter 的 dev 分支, 前前后后大概重装了 3 次, 现在终于是稳定了.
5. 学习成本不小
flutter 算是一种新的开发方式, 语言用 dart 开发, 虽说 dart 很像很像 java, 但是有些细节和 java 不太一样, 所以遇到的时候还是要去查一下.
然后就是 flutter 除了上面说的移除了 xml 的布局, 纯粹用代码写布局外. flutter 的控件这些还是要花时间去掌握. 和 Android 原生的用法不一样, 相对布局的概念也有些差异.
flutter 使用的异步线程也和 java 虚拟机不太一样. 因为 java 里面栈才是线程私有的, 堆和方法区是线程共享的, 这就要考虑堆里面数据的多线程问题. 但是 flutter 里面堆也是线程私有的, 所以不用担心多线程. 但是个人感觉如果不花时间去理解这种模式, 后面肯定是会有问题的, 虽然目前还没遇到(demo).
之前也提到过, 除非一个新项目全部用 flutter 写(也有可能一些功能要原生去实现). 老的项目里面用 flutter, 要用模块的形式接进去. 就要涉及到 flutter 和 Android 原生, iOS 原生相接. 这就代表如果 Android 去开发 flutter, 除了学习 flutter, 后面还是有概率要去看看 iOS 的一些原生开发方式(理想情况是 Android+flutter 和 iOS+flutter). 类似的接 so 库这些也不太一样
适配问题. 而且虽说一套代码在 Android,iOS 上面跑, 但是 Android,iOS 的风格是不一样的. 有开发经验的都知道 ui 给的图, 最明显的就是 titleBar 两端是不一样的.
一个是 Material 一个是 Cupertino 风格. 现在我都是按照 Android 的 material 风格写的, 如果是做线上项目, 肯定也要花时间去适配 iOS 风格的.
不过 Android 开发嘛, 大家都懂得, 各种华为, 小米, oppo 等适配, 不就是多一个 apple 嘛, 哈哈哈.
ps: 现在个人配置: Mac pro(双系统 Mac Windows), 手机一加 5(Android),ipad2018(iOS), 远程 VPS(Linux)
总结 & 后续
总的来说 flutter 还是值得去看一看的, 毕竟是 google 推出来的, 国内闲鱼已经上线了.
至于学习到什么程度需要自己结合实际情况把控了, 如果能运用到公司的项目里面那是最好不过了, 在不荒废原生开发的情况下 all in flutter. 如果公司不使用 flutter, 就看个人的规划和空余时间有多少吧.
毕竟工作日公司要加班, 回去要陪女朋友.
回去要陪女朋友 . emmmm...... 看来我还是有时间的.
flutter 要深入, 还是要花很多时间的. 反正慢慢搞嘛, 又没有明显的 dealine, 白天学 Android, 晚上学点其他的.
大前端的趋势是越来越明显了, 但是谁也说不准, 说不定哪天就突然去世, 还是得靠原生开发.
来源: http://www.jianshu.com/p/1da0cfd3e7d9