日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

flutter中的網絡請求數據獲取詳解_Android

作者:前端那些年 ? 更新時間: 2023-02-26 編程語言

跨平臺的http請求

http包提供了最簡單的發起請求的方式,并且這個包在WEB,ANDROID,IOS上都得到了很好的支持。

需要注意的是,在某些特定的平臺上需要設置一些額外的內容,比如:

ANDROID上必須在manifest(AndroidManifest.xml)文件中進行聲明。

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

macOS上必須在.entitlements進行配置。

<key>com.apple.security.network.client</key>
<true/>

請求數據

從網絡上請求數據大致分為四步:

  • 添加http
  • 通過http包發起請求
  • 將收到的響應數據轉為客戶端可用的數據
  • 展示用戶界面

添加http包

我們只需要在pub.dev文件中添加配置即可:

dependencies:
  http: <latest_version>

然后在代碼中導入http包:

import 'package:http/http.dart' as http;

另外,在安卓中我們需要添加網絡權限:

<!-- Required to fetch data from the internet. -->
<uses-permission android:name="android.permission.INTERNET" />

發起請求

發起請求很簡單:

Future<http.Response> fetchAlbum() {
  return http.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
}

http.get()方法返回一個Future類的數據,這個數據包含了收到的響應數據。 Future是用于處理異步操作的核心Dart類。Future對象表示將來某個時間可能出現的值或錯誤。 http.Response類包含從成功的http調用接收的數據。

將響應轉為常用對象

雖然發出網絡請求很容易,但使用原始的Future<http.Response>并不是很方便。為了讓我們的開發更簡單,我們可以將http.Response轉換為Dart對象。

首先,創建一個包含網絡請求數據的Album類。它包括一個工廠構造函數,用于從JSON創建Album。

class Album {
  final int userId;
  final int id;
  final String title;
  const Album({
    required this.userId,
    required this.id,
    required this.title,
  });
  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  }
}

然后,我們使用以下步驟更新fetchAlbum()函數以返回Future<Album>

  • 使用dart:Convert包將響應體轉換為JSON映射。
  • 如果服務器確實返回了狀態代碼為200的OK響應,則使用fromJson()工廠方法將JSON映射轉換為Album
  • 如果服務器沒有返回狀態代碼為200的OK響應,則拋出異常。(即使在“404 Not Found”服務器響應的情況下,也會拋出異常。不要返回null。這在檢查快照中的數據時很重要,如下所示。)
Future<Album> fetchAlbum() async {
  final response = await http
      .get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

獲取數據

我們可以在initState()didChangeDependencies()方法中調用fetchAlbum()方法。

initState()方法只調用一次,然后再也不會調用。如果我們想選擇重新加載API以響應InheritedWidget的更改,我們可以將調用放入didChangeDependencies()方法中。

class _MyAppState extends State<MyApp> {
  late Future<Album> futureAlbum;
  @override
  void initState() {
    super.initState();
    futureAlbum = fetchAlbum();
  }
  // ···
}

展示數據

要在屏幕上顯示數據,我們可以使用FutureBuilder組件。FutureBuilder組件隨Flutter一起提供,可以輕松處理異步數據源。

我們需要提供兩個參數:

  • 具體的Future
  • builder方法,用來告訴系統渲染什么內容,根據狀態可以選擇加載中等等。
FutureBuilder<Album>(
  future: futureAlbum,
  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 const CircularProgressIndicator();
  },
)

為什么要在initstate中獲取數據?

雖然在build()中調用很方便,但不建議將API調用放在build()方法中。

Flutter每次需要更改視圖中的任何內容時都會調用build()方法,這種情況經常發生。如果將fetchAlbum()方法放置在build()中,則會在每次重建時重復調用,導致應用程序速度減慢。

原文鏈接:https://juejin.cn/post/7186976318595006524

欄目分類
最近更新