最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司21年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
今天要跟大家分享的是Json反序列化的实现。相信做app的同学都会遇到这么一个问题,在向服务器请求数据后,服务器往往会返回一段json字符串。而我们要想更加灵活的使用数据的话需要把json字符串转化成对象。由于flutter只提供了json to Map。而手写反序列化在大型项目中极不稳定,很容易导致解析失败。所以今天给大家介绍的是flutter团队推荐使用的 json_serializable 自动反序列化。
你将学到什么
- flutter中如何解析json对象
- 如何使用自动生成工具生成代码
- 如何测试你的数据
开始json反序列化
第一步:创建mock数据
在实际开发过程中,我们可能会对之前的一些代码进行修改。当我们代码功能复杂并且量足够大的时候,我们需要使用单元测试来保证新添加的代码不会影响之前所写的代码。而服务器的数据经常会变化,所以第一步当然是创建一个我们的mock数据啦。
这里使用了GITHUB/HackerNews的数据(github.com/HackerNews/…)
abstract class JsonString{
static final String mockdata = ‘’’ {
“by” : “dhouston”,
“descendants” : 71,
“id” : 8863,
“kids” : [ 8952, 9224, 8917, 8884, 8887, 8943, 8869, 8958, 9005, 9671, 8940, 9067, 8908, 9055, 8865, 8881, 8872, 8873, 8955, 10403, 8903, 8928, 9125, 8998, 8901, 8902, 8907, 8894, 8878, 8870, 8980, 8934, 8876 ],
“score” : 111,
“time” : 1175714200,
“title” : “My YC app: Dropbox - Throw away your USB drive”,
“type” : “story”,
“url” : “http://www.getdropbox.com/u/2/screencast.html”
}‘’';
}
第二步:添加依赖
在pubspec.yaml中添加如下依赖
dependencies:
Your other regular dependencies here
json_annotation: ^1.2.0
dev_dependencies:
Your other dev_dependencies here
build_runner: ^0.10.2
json_serializable: ^1.5.1
这里需要添加三个依赖,它们分别是:“json_annotation” “build_runner” 和 “json_serializable”。
请注意,yaml配置文件对于缩进要求十分严格,下面的build_runner和json_serializable应该是与flutter_test平级的,千万不要写在flutter_test缩进后,这样它会认为这两个是flutter_test的子集目录!
由于很多朋友在这一步遇到了问题,这里贴出源码
第三步:根据json创建实体类
我们这里根据上面的json数据写好了一个dart的实体类
class Data{
final String by;
final int descendants;
final int id;
final List kids;
final int score;
final int time;
final String title;
final String type;
final String url;
Data({this.by, this.descendants, this.id, this.kids, this.score, this.time,
this.title, this.type, this.url});
}
我们在这里使用了dart语法糖创建了构造函数。具体请参考(www.dartlang.org/guides/lang…)。
第四步:关联实体类文件
我们需要在我们的实体类中关联生成文件。
import ‘package:json_annotation/json_annotation.dart’;
part ‘data.g.dart’;
@JsonSerializable()
class Data {
final String by;
final int descendants;
final int id;
final List kids;
final int score;
final int time;
final String title;
final String type;
@JsonKey(nullable: false)
final String url;
Data({this.by, this.descendants, this.id, this.kids, this.score, this.time,
this.title, this.type, this.url});
刚写完data.g.dart的会报错,这是正常的!因为我们还没生成解析文件
- 为了使实体类文件找到生成文件,我们需要 part ‘data.g.dart’。
第五步:生成Json解析文件
当当当…!这里开始就是重头戏了!!
我们要使用JsonSerializable生成代码的话必须要在需要生成代码的实体类前添加注解@JsonSerializable(),而要使用这个注解我们必须引入json_annotation/json_annotation.dart这个包。
import ‘package:json_annotation/json_annotation.dart’;
@JsonSerializable()
class Data{
final String by;
final int descendants;
final int id;
final List kids;
final int score;
final int time;
final String title;
final String type;
final String url;
Data({this.by, this.descendants, this.id, this.kids, this.score, this.time,
this.title, this.type, this.url});
}
这里需要注意,flutter编码规范dart文件名统一小写,这样可以避免很多问题。ok这样实体类就创建完成啦。
那么问题来了,应该如何生成代码呢?
还记得我们刚才添加的build_runner的依赖吗,这时候我们就需要它来帮忙咯。
build_runner
build_runner是dart团队提供的一个生成dart代码文件的外部包。
我们在当前项目的目录下运行flutter packages pub run build_runner build
运行成功后我们应该能在这个实体类的下面发现一个新的文件
这个data.g.dart就是build_runner根据JsonSerializable生成的json解析文件。 我们来看看这个生成的dart文件
// GENERATED CODE - DO NOT MODIFY BY HAND
part of ‘data.dart’;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Data _$DataFromJson(Map<String, dynamic> json) {
return Data(
by: json[‘by’] as String,
descendants: json[‘descendants’] as int,
id: json[‘id’] as int,
kids: (json[‘kids’] as List)?.map((e) => e as int)?.toList(),
score: json[‘score’] as int,
time: json[‘time’] as int,
title: json[‘title’] as String,
type: json[‘type’] as String,
url: json[‘url’] as String);
}
Map<String, dynamic> _$DataToJson(Data instance) => <String, dynamic>{
‘by’: instance.by,
‘descendants’: instance.descendants,
‘id’: instance.id,
‘kids’: instance.kids,
‘score’: instance.score,
‘time’: instance.time,
‘title’: instance.title,
‘type’: instance.type,
‘url’: instance.url
};
同志们请注意这段代码最上面的注释"// GENERATED CODE - DO NOT MODIFY BY HAND"。你可千万别手写生成文件啊哈哈哈哈。
这段代码生成实体类库的一个part,在老版本part中有一个抽象实体类的mixin,dart中使用基于mixin的继承来解决单继承的局限性。
新版本中声称了两个方法,fromJson和toJson方法,它们能干什么相信大家从名字上就能猜到了。
【对part感兴趣的同学可以参考https://juejin.im/post/6844903649617936392#heading-8 Dart | 浅析dart中库的导入与拆分。
对mixin感兴趣的同学可以在(www.dartlang.org/guides/lang…)了解更多关于mixin的知识。】
- _$DataFromJson:它接收了一个map:Map<String, dynamic>,并将这个Map里的值映射为我们所需要的实体类对象。我们就可以使用这个方法,将存有json数据的map转化为我们需要的实体类对象。
- _$DataToJson:将调用此方法的对象直接根据字段映射成Map。
而这两个都是私有方法,part让两个文件共享作用域与命名空间,所以我们需要将生成的方法暴露给外部。
题外话
不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊
这里我为大家准备了一些我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~
欢迎评论区讨论。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
论区讨论。**
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!