dependencies:
flutter:
sdk: flutter
# The following adds the CupertinoIcons font to your application.
# Usewith the CupertinoIconsclassfor iOS style icons.
cupertino_icons:^1.0.2
http: any
dio:^5.0.2
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';classPhoto{final int albumId;final int id;finalString title;finalString url;finalString thumbnailUrl;constPhoto({
required this.albumId,
required this.id,
required this.title,
required this.url,
required this.thumbnailUrl,});factoryPhoto.fromJson(Map<String,dynamic> json){returnPhoto(
albumId: json['albumId']as int,
id: json['id']as int,
title: json['title']asString,
url: json['url']asString,
thumbnailUrl: json['thumbnailUrl']asString,);}}classAlbum{final int id;finalString title;constAlbum({required this.id, required this.title});factoryAlbum.fromJson(Map<String,dynamic> json){returnAlbum(
id: json['id'],
title: json['title'],);}}voidmain(){runApp(constMyApp());}classMyAppextendsStatefulWidget{constMyApp({super.key});@overrideState<MyApp>createState(){return_MyAppState();}}class _MyAppState extendsState<MyApp>{finalTextEditingController _controller =TextEditingController();Future<Album>? _futureAlbum;@overrideWidgetbuild(BuildContext context){returnMaterialApp(
title:'Create Data Example',
theme:ThemeData(
primarySwatch:Colors.blue,),
home:Scaffold(
appBar:AppBar(
title:constText('Create Data Example'),),
body:Container(
alignment:Alignment.center,
padding:constEdgeInsets.all(8.0),
child:Stack(
children:[FutureBuilder<List<Photo>>(
future:fetchPhotosnew(),
builder:(context, snapshot){if(snapshot.hasError){returnconstCenter(
child:Text('An error has occurred!'),);}elseif(snapshot.hasData){returnPhotosList(photos: snapshot.data!);}else{returnconstCenter(
child:CircularProgressIndicator(),);}},),(_futureAlbum ==null)?buildColumn():buildFutureBuilder(),],))),);}ColumnbuildColumn(){returnColumn(
mainAxisAlignment:MainAxisAlignment.center,
children:<Widget>[TextField(
controller: _controller,
decoration:constInputDecoration(hintText:'Enter Title'),),ElevatedButton(
onPressed:(){setState((){
_futureAlbum =createAlbum(_controller.text);});},
child:constText('Create Data'),),],);}FutureBuilder<Album>buildFutureBuilder(){returnFutureBuilder<Album>(
future: _futureAlbum,
builder:(context, snapshot){if(snapshot.hasData){returnText(snapshot.data!.title);}elseif(snapshot.hasError){returnText('${snapshot.error}');}returnconstCircularProgressIndicator();},);}}classPhotosListextendsStatelessWidget{constPhotosList({super.key, required this.photos});finalList<Photo> photos;@overrideWidgetbuild(BuildContext context){returnGridView.builder(
gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount:2,),
itemCount: photos.length,
itemBuilder:(context, index){returnImage.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.returnFuture.delayed(Duration(milliseconds:20000),(){print("延时20秒执行");returnFuture.value(compute(parsePhotos, response.body));});}//2.dio的方式 get请求BaseOptions options =BaseOptions(//请求基地址,可以包含子路径
baseUrl:Api.BASE_URL,//连接服务器超时时间,单位是毫秒.
connectTimeout:constDuration(milliseconds:10000),//响应流上前后两次接受到数据的间隔,单位为毫秒。
receiveTimeout:constDuration(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,);voidformatError(DioError e){if(e.type ==DioErrorType.connectionTimeout){// It occurs when url is opened timeout.print("连接超时");}elseif(e.type ==DioErrorType.sendTimeout){// It occurs when url is sent timeout.print("请求超时");}elseif(e.type ==DioErrorType.receiveTimeout){//It occurs when receiving timeoutprint("响应超时");}elseif(e.type ==DioErrorType.badResponse){// When the server response, but with a incorrect status, such as 404, 503...print("出现异常");}elseif(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.returnFuture.delayed(Duration(milliseconds:20000),(){print("延时20秒执行");returncompute(parsePhotos, response.data!);});}onDioErrorcatch(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.returnAlbum.fromJson(jsonDecode(response.body));}else{// If the server did not return a 201 CREATED response,// then throw an exception.throwException('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.returnAlbum.fromJson(jsonDecode(response.data!));}else{// If the server did not return a 201 CREATED response,// then throw an exception.throwException('Failed to create album.');}}