flutter3.X Http请求

flutter3.X Http请求

1.AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

2.添加依赖

dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  http: any
  dio: ^5.0.2

3.main.dart 引用包

import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:dio/dio.dart';
import 'package:httpdiotest/common/api.dart';

4.应用

import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:dio/dio.dart';
import 'package:httpdiotest/common/api.dart';

class Photo {
  final int albumId;
  final int id;
  final String title;
  final String url;
  final String thumbnailUrl;

  const Photo({
    required this.albumId,
    required this.id,
    required this.title,
    required this.url,
    required this.thumbnailUrl,
  });

  factory Photo.fromJson(Map<String, dynamic> json) {
    return Photo(
      albumId: json['albumId'] as int,
      id: json['id'] as int,
      title: json['title'] as String,
      url: json['url'] as String,
      thumbnailUrl: json['thumbnailUrl'] as String,
    );
  }
}

class Album {
  final int id;
  final String title;

  const Album({required this.id, required this.title});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['id'],
      title: json['title'],
    );
  }
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  
  State<MyApp> createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  final TextEditingController _controller = TextEditingController();
  Future<Album>? _futureAlbum;

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Create Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Create Data Example'),
          ),
          body: Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.all(8.0),
              child: Stack(
                children: [
                  FutureBuilder<List<Photo>>(
                    future: fetchPhotosnew(),
                    builder: (context, snapshot) {
                      if (snapshot.hasError) {
                        return const Center(
                          child: Text('An error has occurred!'),
                        );
                      } else if (snapshot.hasData) {
                        return PhotosList(photos: snapshot.data!);
                      } else {
                        return const Center(
                          child: CircularProgressIndicator(),
                        );
                      }
                    },
                  ),
                  (_futureAlbum == null) ? buildColumn() : buildFutureBuilder(),
                ],
              ))),
    );
  }

  Column buildColumn() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        TextField(
          controller: _controller,
          decoration: const InputDecoration(hintText: 'Enter Title'),
        ),
        ElevatedButton(
          onPressed: () {
            setState(() {
              _futureAlbum = createAlbum(_controller.text);
            });
          },
          child: const Text('Create Data'),
        ),
      ],
    );
  }

  FutureBuilder<Album> buildFutureBuilder() {
    return FutureBuilder<Album>(
      future: _futureAlbum,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Text(snapshot.data!.title);
        } else if (snapshot.hasError) {
          return Text('${snapshot.error}');
        }

        return const CircularProgressIndicator();
      },
    );
  }
}

class PhotosList extends StatelessWidget {
  const PhotosList({super.key, required this.photos});

  final List<Photo> photos;

  
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: photos.length,
      itemBuilder: (context, index) {
        return Image.network(photos[index].thumbnailUrl);
      },
    );
  }
}

//1.http的方式  get请求
Future<List<Photo>> fetchPhotos(http.Client client) async {
  final response = await client
      .get(Uri.parse('https://jsonplaceholder.typicode.com/photos'));

  // Use the compute function to run parsePhotos in a separate isolate.
  return Future.delayed(Duration(milliseconds: 20000), () {
    print("延时20秒执行");
    return Future.value(compute(parsePhotos, response.body));
  });
}

//2.dio的方式  get请求
BaseOptions options = BaseOptions(
  //请求基地址,可以包含子路径
  baseUrl: Api.BASE_URL,
  //连接服务器超时时间,单位是毫秒.
  connectTimeout: const Duration(milliseconds: 10000),
  //响应流上前后两次接受到数据的间隔,单位为毫秒。
  receiveTimeout: const Duration(milliseconds: 5000),
  //Http请求头.
  headers: {
    //do something
    "version": "1.0.0"
  },
  //请求的Content-Type,默认值是"application/json; charset=utf-8",Headers.formUrlEncodedContentType会自动编码请求体.
  contentType: Headers.formUrlEncodedContentType,
  //表示期望以那种格式(方式)接受响应数据。接受四种类型 `json`, `stream`, `plain`, `bytes`. 默认值是 `json`,
  responseType: ResponseType.plain,
);

void formatError(DioError e) {
  if (e.type == DioErrorType.connectionTimeout) {
    // It occurs when url is opened timeout.
    print("连接超时");
  } else if (e.type == DioErrorType.sendTimeout) {
    // It occurs when url is sent timeout.
    print("请求超时");
  } else if (e.type == DioErrorType.receiveTimeout) {
    //It occurs when receiving timeout
    print("响应超时");
  } else if (e.type == DioErrorType.badResponse) {
    // When the server response, but with a incorrect status, such as 404, 503...
    print("出现异常");
  } else if (e.type == DioErrorType.cancel) {
    // When the request is cancelled, dio will throw a error with this type.
    print("请求取消");
  } else {
    //DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
    print("未知错误");
  }
}

final dio = Dio(options);

//real 请求
Future<List<Photo>> fetchPhotosnew() async {
  try {
    var response = await dio.get<String>('/photos');
    print('get success---------${response.statusCode}');
    // print('get success---------${response.data}');

    // Use the compute function to run parsePhotos in a separate isolate.

    return Future.delayed(Duration(milliseconds: 20000), () {
      print("延时20秒执行");
      return compute(parsePhotos, response.data!);
    });
  } on DioError catch (e) {
    // print('get error---------$e');
    formatError(e);
    rethrow;
  }
}

// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();

  return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}

//------------------------------------------------------------------------------

// //1.http的方式  post请求
Future<Album> createAlbum(String title) async {
  final response = await http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/albums'),
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(<String, String>{
      'title': title,
    }),
  );

  if (response.statusCode == 201) {
    // If the server did return a 201 CREATED response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 201 CREATED response,
    // then throw an exception.
    throw Exception('Failed to create album.');
  }
}

// //2.dio的方式  post请求
Future<Album> createAlbumDio(String title) async {
  final response = await dio.post<String>("/albums",
      data: jsonEncode(<String, String>{
        'title': title,
      }),
      options: Options(headers: {
        Headers.contentLengthHeader: title.length,
        Headers.contentTypeHeader:
            'application/json; charset=UTF-8', // Set the content-length.
      }));

  if (response.statusCode == 201) {
    // If the server did return a 201 CREATED response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.data!));
  } else {
    // If the server did not return a 201 CREATED response,
    // then throw an exception.
    throw Exception('Failed to create album.');
  }
}

5.源代码

flutter Http请求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值