《Flutter 从0到1构建大前端应用》读后感—第6章【使用网络技术与异步编程】

Flutter 《从0到1构建大前端应用》-所有知识点架构

一丶 网络协议简介

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),
      ),
    );
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王睿丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值