如何使用 Dart 保存 API 请求中的图像?

问题描述 投票:0回答:2

我正在使用 Google Maps Places API 查找附近地点的图像。然而,我发现通过发出请求不断重新加载我过去已经加载的图像非常低效且昂贵。但是,我注意到,当我在浏览器中打开请求链接时,我会被重定向到另一个不需要打开请求的页面。如何获取此页面,以便每个图像只需发出一次请求? 我被告知要缓存图像,但我不知道这如何解决任何问题,因为它所做的一切都存储了请求链接。如果这确实是一种适用的方法,我们将不胜感激。

flutter dart google-places-api
2个回答
0
投票

您可以使用 HTTP 客户端遵循重定向并获取最终 URL。这是使用 http 包的示例:

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

Future<String> getFinalImageUrl(String initialUrl) async {
  var response = await http.get(Uri.parse(initialUrl));
  if (response.statusCode == 302) {
    return response.headers['location'];
  }
  return initialUrl;
}

我希望这可以帮助你。


0
投票

解决此问题的最佳方法是使用缓存解决方案,例如,如果您想自己管理图像/URL 缓存逻辑,请使用 flutter_cache_manager,或者使用 cached_network_image 来获取用于图像处理的复合解决方案。

如果您只想缓存图像,以便它们仅在应用程序会话中加载一次,或者可能加载更长时间,具体取决于缓存和图像大小,请使用

cached_network_image
库。在渲染图像小部件时,会发出 HTTP 请求来下载图像并将其放入应用程序的临时缓存目录中以供以后使用。以这种方式加载的图像将通过
CachedNetworkImageProvider
提供程序在后续重新渲染中重复使用。
cached_network_image
库在底层使用
flutter_cache_manager
来处理新条目的插入、陈旧条目的删除,并检查是否重新请求图像而不是从缓存中提供图像。

这是一个最小的演示供您试用:

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: MyPage()));

class MyPage extends StatelessWidget {
  const MyPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            CachedNetworkImage(
              imageUrl: 'https://via.assets.so/img.jpg?w=400&h=400',
              placeholder: (_, __) => const Center(
                child: CupertinoActivityIndicator(),
              ),
              errorWidget: (_, __, ___) => const Center(
                child: Icon(Icons.error),
              ),
            ),
            const SizedBox(height: 24),
            const Text('cached_network_image demo'),
          ],
        ),
      ),
    );
  }
}

我建议您尝试演示并从 API 请求不同尺寸(宽度和高度)的图像,以了解缓存的工作原理。通过相同端点提供的先前缓存图像的后续渲染不会产生额外的 HTTP 请求,如 DevTools 网络部分所示。另外,尝试关闭并重新打开(仅适用于 Android 模拟器)或热重启(适用于 iOS 模拟器)应用程序,以查看缓存在应用程序会话之间是否有效,即使它已终止。

DevTools 网络部分截图

© www.soinside.com 2019 - 2024. All rights reserved.