2024年安卓最全Flutter学习指南:编写第一个应用,2024年最新面试完腾讯我才发现这些知识点竟然没掌握全面了

总结

找工作是个很辛苦的事情,而且一般周期都比较长,有时候既看个人技术,也看运气。第一次找工作,最后的结果虽然不尽如人意,不过收获远比offer大。接下来就是针对自己的不足,好好努力了。

最后为了节约大家的时间,我把我学习所用的资料和面试遇到的问题和答案都整理成了PDF文档

喜欢文章的话请关注、点赞、转发 谢谢!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

return MaterialApp(
// 移动设备使用这个 title 来表示我们的应用。具体一点说,在 Android 设备里,我们点击
// recent 按钮打开最近应用列表的时候,显示的就是这个 title。
title: ‘Our first Flutter app’,
// 应用的“主页” 
home: Scaffold(
appBar: AppBar(
title: Text(‘Flutter rolling demo’), 
), 
// 我们知道,Flutter 里所有的东西都是 widget。为了把按钮放在屏幕的中央,
// 这里使用了 Center(它是一个 widget)。
body: Center( 
child: RaisedButton(  
// 用户点击时候调用
onPressed: _onPressed, 
child: Text(‘roll’),
),
),
),
);
}
void _onPressed() {
// TODO
}

安装、调试(1)

现在,点击 Run,把我们的第一个 Flutter 应用跑起来吧。没有意外的话,你会看到下面这个页面:

image.png

如果你遇到了什么困难,可以查看 tag first_app_step1 的代码:

git clone https://github.com/Jekton/flutter_demo.git
cd flutter_demo
git checkout first_app_step1

由于是第一次写 Flutter 应用,我们对上面的代码是否能够按照预期执行还不是那么有信心,所以我们先打个 log 确认一下,点击按钮后是不是真的会执行 onPress

打 log 可以使用 Dart 提供的 print,但在日志比较多的时候,print 的输出可能会被 Android 丢弃,这个时候 debugPrint 会是更好的选择。对应的日志信息可以在 Dart Console 里查看(View -> Tool Windows -> Run 或者 Mac 上使用 Command+4 打开)。

void _onPressed() {
debugPrint(‘_onPressed’);
}

保存后(会自动 Hot Reload),我们再次点击按钮,在我的设备上,打印出了下面这样的信息:

I/flutter (11297): _onPressed
V/AudioManager(11297): playSoundEffect   effectType: 0
V/AudioManager(11297): querySoundEffectsEnabled…

这里的第一行,就是我们打的。现在我们有足够的自信说,点击按钮后,会执行 _onPressed 方法了。

编写代码(2)

软件开发通常是一个螺旋式上升的过程,不可能通过一次编码、调试就完成。现在,我们开始第二轮迭代。

接下来要做的,便是在 _onPressed 里面弹一个框:

// context 这里使用的是 MyApp.build 的参数
void _onPressed(BuildContext context) {
debugPrint('onPressed’);
showDialog(
context: context,
builder: (
) {
return AlertDialog(
content: Text(‘AlertDialog’),
);
}
);
}

遗憾的是,这一次并不那么顺利。Dialog 没有弹出来,而且报了下面这问题:

I/flutter (11297): Navigator operation requested with a context that does not include a Navigator.
I/flutter (11297): The context used to push or pop routes from the Navigator must be that of a widget that is a
I/flutter (11297): descendant of a Navigator widget.

原因在于,stateless 的 widget 只能用于显示信息,不能有其他动作。所以,该让 StatefulWidget 上场了。

class RollingButton extends StatefulWidget {
// StatefulWidget 需要实现这个方法,返回一个 State
@override
State createState() {
return _RollingState();
}
}
// 可能看起来有点恶心,这里的泛型参数居然是 RollingButton
class _RollingState extends State {
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text(‘Roll’),
onPressed: _onPressed,
);
}
void _onPressed() {
debugPrint('_RollingState.onPressed’);
showDialog(
// 第一个 context 是参数名,第二个 context 是 State 的成员变量
context: context,
builder: (
) {
return AlertDialog(
content: Text(‘AlertDialog’),
);
}
);
}
}

要实现一个 stateful 的 widget,可以继承 StatefulWidget 并在 createState 方法中返回一个 State。除了这一部分,代码跟我们之前写的并没有太大的区别。

剩下的,就是替换 MyApp 里面使用的按钮,修改后的代码如下:

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Our first Flutter app’,
home: Scaffold(
appBar: AppBar(
title: Text(‘Flutter rolling demo’),
),
body: Center(
child: RollingButton(),
),
),
);
}
}

再次运行,点击按钮后,我们将看到梦寐以求的 dialog。

image.png

如果你遇到了麻烦,可以查看 tag first_app_step2 的代码。

最后,我们来实现“roll”:

import ‘dart:math’;
class _RollingState extends State {
final _random = Random();
// …
List _roll() {
final roll1 = _random.nextInt(6) + 1;
final roll2 = _random.nextInt(6) + 1;
return [roll1, roll1];
}
void _onPressed() {
debugPrint(‘_RollingState._onPressed’);
final rollResults = roll();
showDialog(
// 第一个 context 是参数名,第二个 context 是 State 的成员变量
context: context,
builder: (
) {
return AlertDialog(
content: Text(‘Roll result: ( r o l l R e s u l t s [ 0 ] ,   {rollResults[0]},  rollResults[0], {rollResults[1]})’),
);
}
);
}
}

安装、调试(2)

还是一样,重新运行后,我们就能够看到每次点击按钮的结果随机地出现 [1, 6] 中的数……慢着,怎么弹出的消息里的两个号码总是一样的!好吧,肯定是哪里出错了。

这次,我们不采用打 log 的方法,改用 debugger 来调试。

1. 在 final rollResults = _roll() 这一行打个断点
2. 然后点击 Debug main.dart 开始调试
3. 点击 APP 里的 Roll 按钮

现在,应用停在了我们所打的断点处:

image.png

接下来:

1. Step Into 进入 _roll 方法
2. 进入 _roll 后,Step Over 一行一行执行。

image.png

这里我们看到,两次 random 确实产生了不同的结果。我们继续:

  1. 还是 Step Over,这个时候 _roll 就返回了
  2. 切换到 Variables 这个选项卡,查看 rollResults 的值

image.png

可以发现,两个结果居然变成一样的了。再往回查看一下代码,我们写的是 return [roll1, roll1]。修改后一个为 roll2,程序就能够按预期的正常执行了。

最终的代码,可以看 tag first_app_done。

调试总结

本篇文章其实介绍了两种调试方法:打 log 和 debugger。虽然现在 Flutter 提供的 log 工具比较简陋,可以预期未来还会进一步完善。

使用打 log 的方式,好处在于不会对执行流程产生较大的影响,在多线程环境尤为有用。它的速度也比较快,不需要我们去单步执行。不足之处在于,如果原先没有对应的 log,我们只能修改代码重新运行,才能查看相应的状态。对于线上的应用,我们也只能够通过分析 log 来定位问题。

debugger 跟打 log 方式是互补的。使用 debugger 时,我们可以随意查看我们需要知道的变量的值,一步一步近距离观察代码的运行状态。坏处当然就是太慢了。在什么时候使用什么方法,需要一些经验;但有时候就全凭个人喜好了,没有优劣之分。

最后

现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水!

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!

Android架构师之路很漫长,一起共勉吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

师之路很漫长,一起共勉吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值