網絡請求是APP開發中至關重要的一步,回想一下Android開發中的Retrofit框架或者Volley框架,iOS開發中AFNetworking框架。如果使用Volley進行網絡請求,我們需要new一個StringRequest請求,在裏面回調成功和失敗的方法,用GsonFormmater等類似工具解析json串,然後將這個請求添加到隊列,這中間要給予用戶友好的提示,即顯示與隱藏加載框,甚至是下拉刷新功能的實現,如果要保持登錄狀態,還需要將Session信息添加到請求的頭部。成熟的網絡請求框架像Volley很容易實現這些功能,Flutter中的網絡請求是否能夠實現這些功能呢,如何實現呢?
這篇文章主要介紹如何在Flutter中進行網絡請求,包括基本的網絡請求,對服務器返回的json進行解析,構造json,加載框顯示與隱藏。
一、完整的網絡請求過程
打開InteliJ IDEA,新建一個Flutter工程,在左側工程結構裏面的pubspec.yaml文件裏面添加網絡請求的依賴
http: '>=0.11.3+12'
將main.dart裏面的代碼全部刪除,然後重新寫我們的代碼,先導包:
import 'package:flutter/material.dart';//導入系統基礎包
import 'package:flutter/services.dart';//導入網絡請求相關的包
然後獲取http對象
var httpclient=createHttpClient();//獲取http對象
用async…await..發送網絡請求並讀取結果:
_postData() async{
response=await httpclient.read(url);//發送網絡請求,read()表示讀取返回的結果,get()表示不讀取返回的結果
print('Response=$response');
}
上面就是一次完整的網絡請求的核心代碼,好像並不複雜吧?完整的代碼如下,直接複製到main.dart,替換掉原來的代碼即可運行:
import 'package:flutter/material.dart';//導入系統基礎包
import 'package:flutter/services.dart';//導入網絡請求相關的包
void main(){
runApp(new MaterialApp(home: new ClickEvent(),));
}
class ClickEvent extends StatefulWidget{
@override
_ClickEventState createState() {
return new _ClickEventState();
}
}
class _ClickEventState extends State<ClickEvent>{
var httpclient=createHttpClient();//獲取http對象
var url='https://api.github.com/';
var response;
_postData() async{
response=await httpclient.read(url);//發送網絡請求,read()表示讀取返回的結果,get()表示不讀取返回的結果
print('Response=$response');
}
@override
Widget build(BuildContext context) {
return new Scaffold(appBar: new AppBar(title: new Text('網絡請求'),),
floatingActionButton: new FloatingActionButton(child: new Text('獲取數據'),onPressed: _postData),);//點擊後調用網絡請求方法
}
}
運行結果爲:
上面就是https://api.github.com/這個接口返回的json串,至此我們已經能夠從服務器獲取網絡數據了,怎麼樣,比想象中簡單吧。
二、解析服務器返回的json數據
先導入json相關的包
import 'dart:convert';
如果返回的數據結果類似於:
['foo', { 'bar': 499 }]
可以這樣解析
Map data= JSON.decode(response);
data[1]['bar'];
如果返回的數據結構類似於:
{"current_user_url":"https://api.github.com/user"}
可以這樣解析:
Map data= JSON.decode(response);
var url1= data['current_user_url'];
解析結果爲:
current_user_url:https://api.github.com/user
三、等待動畫的顯示與關閉
先新建一個對話框(圓圈)控件,用來顯示,核心代碼是
new CircularProgressIndicator()//這是圓圈對話框,還有條形對話框的。
然後用定時器不斷去回調結果,代碼如下:
class ShowProgress extends StatefulWidget {
ShowProgress(this.requestCallback);
final Future<Null> requestCallback;//這裏Null表示回調的時候不指定類型
@override
_ShowProgressState createState() => new _ShowProgressState();
}
class _ShowProgressState extends State<ShowProgress> {
@override
initState() {
super.initState();
new Timer(new Duration(milliseconds: 10), () {//每隔10ms回調一次
widget.requestCallback.then((Null) {//這裏Null表示回調的時候不指定類型
Navigator.of(context).pop();//所以pop()裏面不需要傳參,這裏關閉對話框並獲取回調的值
});
});
}
@override
Widget build(BuildContext context) {
return new Center(
child: new CircularProgressIndicator(),//獲取控件實例
);
}
}
點擊“獲取數據”按鈕,將網絡請求的方法_postData作爲參數傳遞給ShowProgress顯示對話框,下面代碼功能主要是展示對話框,核心代碼如下:
Future<Null> _myClick() {
return showDialog<Null>(
context: context,
barrierDismissible: true, // false表示必須點擊按鈕才能關閉
child:new ShowProgress(_postData())//將網絡請求的方法_postData作爲參數傳遞給ShowProgress顯示對話框
);
完整代碼如下,直接複製到main.dart即可運行:
import 'dart:async';
import 'package:flutter/material.dart';//導入系統基礎包
import 'package:flutter/services.dart';//導入網絡請求相關的包
import 'dart:convert';
void main(){
runApp(new MaterialApp(home: new ClickEvent(),));
}
class ShowProgress extends StatefulWidget {
ShowProgress(this.requestCallback);
final Future<Null> requestCallback;//這裏Null表示回調的時候不指定類型
@override
_ShowProgressState createState() => new _ShowProgressState();
}
class _ShowProgressState extends State<ShowProgress> {
@override
initState() {
super.initState();
new Timer(new Duration(milliseconds: 10), () {//每隔10ms回調一次
widget.requestCallback.then((Null) {//這裏Null表示回調的時候不指定類型
Navigator.of(context).pop();//所以pop()裏面不需要傳參,這裏關閉對話框並獲取回調的值
});
});
}
@override
Widget build(BuildContext context) {
return new Center(
child: new CircularProgressIndicator(),
);
}
}
////////////上面是對話框控件,下面是按鈕控件/////////////////
class ClickEvent extends StatefulWidget{
@override
_ClickEventState createState() {
return new _ClickEventState();
}
}
class _ClickEventState extends State<ClickEvent>{
Future<Null> _myClick() {
return showDialog<Null>(
context: context,
barrierDismissible: true, // false表示必須點擊按鈕才能關閉
child:new ShowProgress(_postData())//將網絡請求的方法_postData作爲參數傳遞給ShowProgress顯示對話框
);
}
var httpclient=createHttpClient();//獲取http對象
var url='https://api.github.com/';
var response;
//核心的網絡請求方法
_postData() async{
response=await httpclient.read(url);//發送網絡請求,read()表示讀取返回的結果,get()表示不讀取返回的結果
print('Response=$response');
Map data= JSON.decode(response);
var url1= data['current_user_url'];
print('current_user_url:$url1');
}
@override
Widget build(BuildContext context) {
return new Scaffold(appBar: new AppBar(title: new Text('網絡請求'),),
floatingActionButton: new FloatingActionButton(child: new Text('獲取數據'),onPressed: _myClick),);
}
}
運行結果爲:
從圖中可以看到,收到服務器響應後就關閉了對話框,達到了我們的目的。
上面講解了一次基本的網絡請求,包括獲取數據,解析數據,顯示等待動畫。當然,成熟的網絡框架遠不止這些,還包括緩存處理,超時處理,異常處理,封裝等等,這些我們以後都會涉及到。
如果看完這篇文章您有所收穫,不忘點個贊或者關注一下留個言什麼的,您的鼓勵是我前進的動力,謝謝。