前言
Flutter
是Google
开源的构建用户界面(UI
)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web
、桌面和嵌入式平台。Flutter
开源、免费,拥有宽松的开源协议,适合商业项目。目前,Flutter
已推出稳定的2.0版本。也是目前最火的跨平台开发工具之一
Dart支持的API请求
之前在Dart语言的学习中,我们直接可以很方便的使用Dart支持的网络请求,在Flutter
中也一样,直接这样就可以获取数据源并将其进行展示
readData() async {
HttpClientResponse response = await getBaiduData();
String res = await response.transform(utf8.decoder).join();
setState(() {
data = res;
});
}
getBaiduData() async {
HttpClient client = HttpClient();
var request = await client.getUrl(Uri.http("www.baidu.com", ""));
var response = await request.close();
return response;
}
Http库
Http库也是我们常用的网络请求框架
添加依赖
http: ^0.12.2
https://github.com/dart-lang/http
数据请求与展示
class HomePageStates extends State
with SingleTickerProviderStateMixin {
String data = "";
bool isShowLoading = false;
@override
void initState() {
super.initState();
}
getData() async {
setState(() {
isShowLoading = true;
});
var http = Client();
Response response = await http.get("https://jsonplaceholder.typicode.com/todos/1");
setState(() {
data = response.body;
isShowLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
centerTitle: true,
),
body: Stack(
children: [
Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('$data'),
Ink(
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(20)),
child: InkWell(
borderRadius: BorderRadius.circular(20),
onTap: () {
getData();
},
splashColor: Colors.white,
child: Container(
width: 100,
height: 40,
alignment: Alignment.center,
child: Text(
'Get',
style: TextStyle(color: Colors.white),
),
),
),
),
],
),
),
Visibility(
visible: isShowLoading,
child: Container(
alignment: Alignment.center,
child: Container(
width: double.maxFinite,
height: double.maxFinite,
child: Center(
child: SizedBox(
height: 40,
width: 40,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.blue),
),
),
),
),
))
],
));
}
}
dio
dio
库是一个更强大的网络请求框架,支持更多的网络请求设置,拦截器,超时,Cookie
,文传等各种设置
https://github.com/flutterchina/dio
添加依赖
dio: ^4.0.1
发起一个简单的请求
getData() async {
setState(() {
isShowLoading = true;
});
var dio = Dio();
var response =
await dio.get("https://jsonplaceholder.typicode.com/todos/1");
data = response.data.toString();
setState(() {
data = response.data.toString();
isShowLoading = false;
});
}
添加一个异常处理
当访问出现异常时,比如资源访问失败,访问超时等
这里由于使用了await
的同步调用,所以需要使用try catch
进行异常捕获,当api调用失败时会返回DioError
里面封装了错误状态码,错误信息,以及错误类型DioErrorType
用于做判断
enum DioErrorType {
/// It occurs when url is opened timeout.
connectTimeout,
/// It occurs when url is sent timeout.
sendTimeout,
///It occurs when receiving timeout.
receiveTimeout,
/// When the server response, but with a incorrect status, such as 404, 503...
response,
/// When the request is cancelled, dio will throw a error with this type.
cancel,
/// Default error type, Some other Error. In this case, you can
/// use the DioError.error if it is not null.
other,
}
这里我使用错误的链接访问
getData() async {
setState(() {
isShowLoading = true;
});
try {
var dio = Dio();
var response =
await dio.get("https://jsonplaceholder.typicode.com/todos/1test");
data = response.data.toString();
} on DioError catch (e) {
data =
"error ${e.type}---${e.response?.statusCode}---${e.response?.statusMessage}";
} catch (e) {
//other exception
data = "other error ${e.toString()}";
} finally {
setState(() {
isShowLoading = false;
});
}
}
访问超时处理
某些时候当服务不稳定时,会导致请求时间过长,可以设置api
的请求超时时间,这里为了测试我们设置1
毫秒的超时时间
var dio = Dio(BaseOptions(receiveTimeout: 1,connectTimeout: 1,sendTimeout: 1));
添加拦截器
拦截器是API请求的很重要一部分,我们可以全局拦截发出去的请求数据比如为其添加特殊的Header
,或者可以拦截返回的数据信息用来做一些公共处理或者打印日志
添加库提供的日志拦截器,方便我们进行请求调试
var dio = Dio(BaseOptions(receiveTimeout: 10000,connectTimeout: 10000,sendTimeout: 10000)).interceptors.add(LogInterceptor());
也可以自定义拦截器,将请求的额链接替换到https://jsonplaceholder.typicode.com/todos/2
dio.interceptors.add(InterceptorsWrapper(onRequest: (options,handler){
options.headers['from'] = 'Mike_Test';
options.path = "https://jsonplaceholder.typicode.com/todos/2";
handler.next(options);
}));
数据转换
通常情况下我们会将API
返回的Jason
数据转换为我们的实体类,这样会方便我们获取其中的字段用于设置和使用
var maps = json.decode("{\"id\":\"2\"}");
var model = ResponseModel(maps["id"]);
print(model.id);
也可以直接安装插件JsonToDart去创建对应的实体类,这样也避免手动写字符串的风险
https://plugins.jetbrains.com/plugin/12562-jsontodart-json-to-dart-
/// id : "2"
class ResponseModel {
ResponseModel({
required String id,}){
_id = id;
}
ResponseModel.fromJson(dynamic json) {
_id = json['id'];
}
String _id ="";
String get id => _id;
Map toJson() {
final map = {};
map['id'] = _id;
return map;
}
}
var model = ResponseModel.fromJson(json.decode("{\"id\":\"2\"}"));
print('${model.id}');
欢迎关注Mike的
Android 知识整理