一丶 网络协议简介
1.HTTP协议简介
2.HTTP2.0 能给我们带来什么
3.HTTPS
二丶 网络编程
1.HttpClient
点击请求网络后返回结果如下:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
class HttpClientTest extends StatefulWidget {
HttpClientTest({Key key, this.title}) : super(key: key);
final String title;
@override
_HttpClientTestState createState() => _HttpClientTestState();
}
class _HttpClientTestState extends State<HttpClientTest> {
String _responseText = "";
//HttpClient get请求
_loadData() async {
try {
HttpClient httpClient = new HttpClient(); //客户端
HttpClientRequest request = await httpClient.getUrl(Uri.parse("https://www.phei.com.cn")); //get 请求
HttpClientResponse response = await request.close(); //得到响应对象,同时关闭 request
_responseText = await response.transform(Utf8Decoder()).join(); //将响应结果转换为 utf-8 编码
print(_responseText); //打印响应回来的结果
httpClient.close(); //HttpClient 关闭
} catch (_) {
print('请求异常:' + _.toString());
}
}
//HttpClient post请求
_loadDataPostMethod() async {
try {
HttpClient httpClient = new HttpClient(); //客户端
HttpClientRequest request = await httpClient.postUrl(Uri.parse("https://post.example.com")); //post 请求
request.headers.set('content-type', 'application/json'); //设置请求头
Map jsonMap = {'userid': '10000'}; // 创建Map数据
request.add(utf8.encode(json.encode(jsonMap))); //将数据加入到请求对象中同时转换成 utf-8编码
HttpClientResponse response = await request.close(); //得到响应对象,同时关闭 request
_responseText = await response.transform(Utf8Decoder()).join(); //将响应结果转换为 utf-8 编码
print(_responseText); //打印响应回来的结果
httpClient.close(); //HttpClient 关闭
} catch (_) {
print('请求异常:' + _.toString());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("HttpClient"),
),
body: Column(
children: <Widget>[
RaisedButton(
child: Text('HttpClient的get方式请求网络'),
onPressed: () {
_loadData(); //get请求网络
},
)
],
),
);
}
}
2.http库
结果和上面一样,不过http库要记得导入第三方依赖
http: ^0.12.0+1
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; //第三方依赖: http: ^0.12.0+1
class HttpTest extends StatefulWidget {
HttpTest({Key key, this.title}) : super(key: key);
final String title;
@override
_HttpTestState createState() => _HttpTestState();
}
class _HttpTestState extends State<HttpTest> {
_loadData() async {
var client = http.Client(); //客户端
var uri = Uri.parse("https://www.phei.com.cn"); //请求连接
http.Response response = await client.get(uri); //get 请求
print(utf8.decode(response.bodyBytes)); //utf8编码 把网页获取的内容进行转码
client.close(); //关闭
}
_loadDataPostMethod() async {
var client = http.Client(); //客户端
Map<String, String> headerMap = {'userid': '10000'}; //创建Map 数据
http.Response response = await client
.post("https://www.phei.com.cn", headers: headerMap, body: {}); //post请求并发送数据
print(utf8.decode(response.bodyBytes)); //utf8编码 把网页获取的内容进行转码
client.close(); //关闭
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("http"),
),
body: Column(
children: <Widget>[
RaisedButton(
child: Text('http的get方式请求网络'),
onPressed: () {
_loadData();
},
)
],
),
);
}
}
三丶 JSON解析
1.JSON 转成 Dart 对象
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Movie> fetchPost() async {
final response = await http.get('http://172.20.10.3:3000/movies/detail/1'); //get请求
if (response.statusCode == 200) { //若成功返回200
//将JSON数据转换成Map类型或List类型,如果是一个JSON对象,返回值是Map,如果是数组,返回值:List
return Movie.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
class Movie {
final String title;
Movie({this.title});
factory Movie.fromJson(Map<String, dynamic> json) {
return Movie(title: json['title']);
}
}
class HttpDemo extends StatefulWidget { //入口
@override
_HttpDemoState createState() => new _HttpDemoState(movie: fetchPost());
}
class _HttpDemoState extends State<HttpDemo> {
final Future<Movie> movie;
_HttpDemoState({Key key, this.movie});
@override
Widget build(BuildContext context) {
return new Scaffold(
body: Center(
child: FutureBuilder<Movie>( //
future: movie,
builder: (context, snapshot) {
if (snapshot.hasData) { //若数据拿到
return Text(snapshot.data.title); //显示标题
} else if (snapshot.hasError) { //若数据异常
return Text("${snapshot.error}"); //打印报错信息
}
// By default, show a loading spinner
return CircularProgressIndicator(); //圆形进度条
},
)
)
);
}
}
2.一个完整的例子
3.根据JSON用工具生成实体类
四丶 dio库
导入第三方库: dio: ^2.0.0
1.基本用法
点击请求网络后返回结果如下:
import 'package:dio/dio.dart'; //第三方库:dio: ^2.0.0
import 'package:flutter/material.dart';
class DioTest extends StatefulWidget {
DioTest({Key key, this.title}) : super(key: key);
final String title;
@override
_DioTestState createState() => _DioTestState();
}
class _DioTestState extends State<DioTest> {
_loadData() async {
try {
Response response = await Dio().get("https://www.phei.com.cn"); //get请求
print(response); //打印响应结果
} catch (e) {
print(e);
}
}
_loadDataPostMethod() async {
try {
Response response = await Dio().post("https://www.phei.com.cn", data: {}); //post请求
print(response); //打印响应结果
} catch (e) {
print(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("http"),
),
body: Column(
children: <Widget>[
RaisedButton(
child: Text('dio的get方式请求网络'),
onPressed: () {
_loadData();
},
)
],
),
);
}
}
2.dio单例
3.dio拦截器
4.dio拦截器链
5.dio适配器
6.dio库总结
五丶 异步编程
1.isolate
2.event loop
这里有两点需要说明:
【1】Future.delayed表示延迟执行,在设定的延迟时间到了之后,才会被放在event loop 队列尾部。
【2】Future.then 里的任务不会加入到 event queue 中,要保证异步任务 的执行顺序就一定要用 then。
Future表示“将来”的意思,代表将来会被执行的代码逻辑。每次创建一个Future,都在event loop 里添加一条记录,如图:
import 'dart:async';
void main() {
print('main #1 of 2');
scheduleMicrotask(() => print('microtask #1 of 3'));
new Future.delayed(
new Duration(seconds: 1), () => print('future #1 delayed'));
new Future(() => print('future #2 of 4'))
.then((_) => print('future #2a'))
.then((_) {
print('future #2b');
scheduleMicrotask(() => print('microtask #0 from future #2b'));
})
.then((_) => print('future #2c'))
.then((_) => print('future #2d'));
scheduleMicrotask(() => print('microtask #2 of 3'));
new Future(() => print('future #3 of 4'))
.then((_) => new Future(() => print('future #3a a new future')))
.then((_) => print('future #3b'))
.then((_) => print('future #3c'));
new Future(() => print('future #4 of 4'))
.then((_) {
new Future(() => print('future #4a'));
})
.then((_) => print('future #4b'))
.then((_) => print('future #4c'));
scheduleMicrotask(() => print('microtask #3 of 3'));
print('main #2 of 2');
}
3.线程模型与isolate
4.创建单独的isolate
import 'dart:async';
import 'dart:isolate';
main() async {
// isolate所需的参数,必须要有SendPort,SendPort需要ReceivePort来创建
final receivePort = new ReceivePort();
// 开始创建isolate, Isolate.spawn函数是isolate.dart里的代码,_isolate是我们自己实现的函数
/**
* _isolate是我们自己实现的函数
* receivePort 接收港口
*/
await Isolate.spawn(_isolate, receivePort.sendPort);
// 发送的第一个message,是它的SendPort
var sendPort = await receivePort.first;
var msg = await sendReceive(sendPort, "foo");
print('received $msg');
msg = await sendReceive(sendPort, "bar");
print('received $msg');
}
/// 新isolate的入口函数
_isolate(SendPort replyTo) async {
// 实例化一个ReceivePort 以接收消息
var port = new ReceivePort();
// 把它的sendPort发送给宿主isolate,以便宿主可以给它发送消息
replyTo.send(port.sendPort);
// 监听消息,从port里取
await for (var msg in port) {
var data = msg[0];
SendPort replyTo = msg[1];
replyTo.send('应答:' + data);
if (data == "bar") port.close(); //关闭
}
}
/// 对某个port发送消息,并接收结果
Future sendReceive(SendPort port, msg) {
ReceivePort response = new ReceivePort();
port.send([msg, response.sendPort]);
return response.first;
}
5.Stream事件流
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final StreamController<int> _streamController = StreamController<int>(); //事件流管理员
int _counter = 0; //数值
@override
void dispose() {
_streamController.close(); //关闭
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>(
stream: _streamController.stream, //事件流
initialData: 0, //初始数据
/**
* BuildContext 建立上下文
* AsyncSnapshot 异步抓拍
*/
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Text(
'${snapshot.data}', //抓拍数据
style: Theme.of(context).textTheme.display1,
);
}),
Text(
'$_counter', //数据
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_streamController.sink.add(++_counter); //将当前整型的 _counter 数值传入到事件流管理员的水槽中
},
tooltip: 'Increment', //提示框
child: Icon(Icons.add),
),
);
}
}