Flutter:如何更快地获取数据?

发布于 1周前 作者 h691938207 来自 Flutter

Flutter:如何更快地获取数据?

在 Flutter 开发中,如果你需要从多个 API 接口获取数据,并且这些请求之间互不依赖,那么并行发起请求会显著提高数据获取的速度。以下是一个详细的示例,展示了如何分别使用串行和并行的方式获取数据,并对比这两种方法。

代码示例-1:串行请求

在这种方法中,每个 HTTP 请求必须等前一个请求完成才能继续执行。

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Serial Requests Example'),
        ),
        body: Center(
          child: SerialRequestExample(),
        ),
      ),
    );
  }
}

class SerialRequestExample extends StatefulWidget {
  @override
  _SerialRequestExampleState createState() => _SerialRequestExampleState();
}

class _SerialRequestExampleState extends State<SerialRequestExample> {
  String todos = '';
  String posts = '';
  String users = '';

  @override
  void initState() {
    super.initState();
    _fetchDataSerially();
  }

  Future<void> _fetchDataSerially() async {
    todos = await fetchData('https://api.example.com/todos');
    setState(() {});
    posts = await fetchData('https://api.example.com/posts');
    setState(() {});
    users = await fetchData('https://api.example.com/users');
    setState(() {});
  }

  Future<String> fetchData(String url) async {
    final response = await http.get(Uri.parse(url));
    return jsonDecode(response.body).toString();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Todos: $todos'),
        Text('Posts: $posts'),
        Text('Users: $users'),
      ],
    );
  }
}

代码示例-2:并行请求

在这种方法中,所有三个请求并行发起,可以同时发送,互不依赖。

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Parallel Requests Example'),
        ),
        body: Center(
          child: ParallelRequestExample(),
        ),
      ),
    );
  }
}

class ParallelRequestExample extends StatefulWidget {
  @override
  _ParallelRequestExampleState createState() => _ParallelRequestExampleState();
}

class _ParallelRequestExampleState extends State<ParallelRequestExample> {
  String todos = '';
  String posts = '';
  String users = '';

  @override
  void initState() {
    super.initState();
    _fetchDataParallelly();
  }

  Future<void> _fetchDataParallelly() async {
    List<Future<String>> futures = [
      fetchData('https://api.example.com/todos'),
      fetchData('https://api.example.com/posts'),
      fetchData('https://api.example.com/users'),
    ];

    List<String> results = await Future.wait(futures);
    setState(() {
      todos = results[0];
      posts = results[1];
      users = results[2];
    });
  }

  Future<String> fetchData(String url) async {
    final response = await http.get(Uri.parse(url));
    return jsonDecode(response.body).toString();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Todos: $todos'),
        Text('Posts: $posts'),
        Text('Users: $users'),
      ],
    );
  }
}

主要区别

  • 串行请求:每个请求依赖于前一个请求的结果,必须等前一个请求完成才能继续执行。
  • 并行请求:所有三个请求并行发起,可以同时发送,互不依赖,可以显著提高数据获取的速度。

完整输出

将上述代码分别复制到你的 Flutter 项目中,运行后即可看到串行和并行请求的效果。通过对比,你可以明显感受到并行请求在数据获取速度上的优势。


更多关于Flutter:如何更快地获取数据?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter:如何更快地获取数据?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,提高数据获取速度通常涉及优化网络请求、数据处理和UI渲染等多个方面。以下是一些具体的代码示例和策略,旨在帮助你更快地获取和展示数据。

1. 使用高效的HTTP库

Flutter中常用的HTTP库包括diohttpdio提供了更丰富的功能和更好的性能。以下是一个使用dio库进行网络请求的示例:

import 'package:dio/dio.dart';

// 创建Dio实例
final Dio dio = Dio();

// 发起GET请求
Future<Map<String, dynamic>> fetchData() async {
  try {
    Response response = await dio.get('https://api.example.com/data');
    return response.data;
  } catch (e) {
    print("Error fetching data: $e");
    return {};
  }
}

2. 缓存数据

为了减少重复的网络请求,可以使用缓存机制。dio库可以与dio_cache_interceptor结合使用来实现数据缓存。

import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';

// 创建缓存拦截器
final cacheInterceptor = CacheInterceptor(
  config: CacheConfig(
    baseUrl: 'https://api.example.com/',
    maxAge: Duration(minutes: 10), // 缓存有效期
  )
);

// 创建Dio实例并添加缓存拦截器
final Dio dio = Dio()
  ..options.baseUrl = 'https://api.example.com/'
  ..interceptors.add(cacheInterceptor);

// 发起GET请求,数据将自动缓存
Future<Map<String, dynamic>> fetchCachedData() async {
  try {
    Response response = await dio.get('/data');
    return response.data;
  } catch (e) {
    print("Error fetching cached data: $e");
    return {};
  }
}

3. 使用异步和并发

Flutter的UI线程是单线程的,因此长时间运行的任务(如网络请求)应该在后台线程中执行。使用asyncawait关键字可以简化异步编程。

Future<void> fetchDataAndUpdateUI() async {
  // 发起网络请求并等待结果
  Map<String, dynamic> data = await fetchData();

  // 更新UI
  setState(() {
    // 例如,将获取的数据赋值给某个状态变量
    this.dataList = data['items'];
  });
}

// 在某个生命周期方法或按钮点击事件中调用
@override
void initState() {
  super.initState();
  fetchDataAndUpdateUI();
}

4. 优化数据处理

如果数据需要处理(如解析JSON、映射数据等),确保这些操作尽可能高效。使用Dart的内置函数和集合操作可以提高性能。

// 示例:将JSON数组映射为自定义对象列表
List<MyData> mapToList(List<Map<String, dynamic>> jsonList) {
  return jsonList.map((json) => MyData.fromJson(json)).toList();
}

// 自定义数据类
class MyData {
  String id;
  String name;

  MyData({required this.id, required this.name});

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

5. 使用分页和懒加载

对于大量数据,可以使用分页和懒加载技术来减少一次性加载的数据量。

// 示例:分页请求数据
Future<List<MyData>> fetchPage(int page) async {
  try {
    Response response = await dio.get('/data', queryParameters: {'page': page});
    List<Map<String, dynamic>> jsonList = response.data['items'];
    return mapToList(jsonList);
  } catch (e) {
    print("Error fetching page data: $e");
    return [];
  }
}

// 在UI中展示分页数据
ListView.builder(
  itemCount: pageCount * itemsPerPage, // 总项数
  itemBuilder: (context, index) {
    int page = index / itemsPerPage;
    int itemIndex = index % itemsPerPage;
    // 懒加载:仅在需要时加载页面数据
    if (!_pages[page].isLoaded) {
      _pages[page] = Future.value(fetchPage(page + 1));
    }
    return FutureBuilder<List<MyData>>(
      future: _pages[page],
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return Text(snapshot.data?[itemIndex].name ?? '');
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  },
);

通过上述方法,你可以显著提高Flutter应用中数据获取和展示的速度。

回到顶部