CachedNetworkImage: khái niệm chính và widget ImageProvider

Tác giả: IT Sectr Đã đăng: 2026-05-05 Thời gian đọc: 8 phút

CachedNetworkImage là widget Flutter để tải và lưu đệm hình ảnh từ mạng với hỗ trợ chỉ báo tiến trình, placeholder và xử lý lỗi. Theo trang gói chính thức, thư viện dựa trên flutter_cache_manager và cung cấp bộ nhớ đệm tự động trên đĩa với TTL có thể cấu hình. CachedNetworkImage là giải pháp tiêu chuẩn để tải hình ảnh trong các ứng dụng Flutter có bộ nhớ đệm.

Những điểm chính

  • CachedNetworkImage — widget Flutter để tải và lưu đệm hình ảnh từ mạng với quản lý bộ nhớ đệm tự động.
  • flutter_cache_manager — gói cơ bản triển khai bộ nhớ đệm hai cấp (tệp + trong bộ nhớ) với lập chỉ mục SQLite.
  • ImageProvider — cơ chế của Flutter để lấy hình ảnh đã giải mã một cách bất đồng bộ từ bất kỳ nguồn nào.
  • Chỉ báo tiến trình được tích hợp trong widget và hiển thị phần trăm tải xuống qua tham số builder progressIndicatorBuilder.
  • Xử lý lỗi — widget hiển thị errorWidget khi tải thất bại, thay thế hình ảnh hỏng bằng placeholder.

CachedNetworkImage là gì?

CachedNetworkImage là widget Flutter từ gói cùng tên trên pub.dev cung cấp khả năng tải hình ảnh từ mạng với bộ nhớ đệm tự động. Nó là một lớp bao bọc xung quanh Image.network tiêu chuẩn, thêm bộ nhớ đệm tệp, chỉ báo tiến trình và xử lý lỗi tùy chỉnh.

Bên trong, CachedNetworkImage sử dụng flutter_cache_manager — trình quản lý bộ nhớ đệm với cơ sở dữ liệu SQLite để theo dõi tệp. Ở yêu cầu đầu tiên, hình ảnh được tải xuống từ mạng, lưu vào đĩa và ở các yêu cầu tiếp theo được phục vụ từ bộ nhớ đệm có tính đến TTL (mặc định 7 ngày). Bộ nhớ đệm trong bộ nhớ được quản lý bởi ImageCache tiêu chuẩn của Flutter.

Gói này có hơn 4.000 lượt thích trên pub.dev và được sử dụng trong hàng nghìn dự án Flutter. CachedNetworkImage hỗ trợ tất cả các nền tảng Flutter: Android, iOS, Web, macOS, Windows và Linux. Nhờ API thống nhất, các nhà phát triển có được khả năng tải hình ảnh đa nền tảng mà không cần mã dành riêng cho từng nền tảng.

Bộ nhớ đệm hình ảnh trong Flutter hoạt động như thế nào

Flutter sử dụng hệ thống bộ nhớ đệm hai cấp: ImageCache (bộ nhớ) và flutter_cache_manager (đĩa + SQLite). ImageCache là bộ nhớ đệm toàn cục của hình ảnh đã giải mã với giới hạn về số lượng (mặc định 1000) và kích thước (mặc định 100 MB). flutter_cache_manager quản lý các tệp trên đĩa và siêu dữ liệu của chúng.

Trình tự tìm kiếm

Khi CachedNetworkImage nhận được yêu cầu hình ảnh, trước tiên nó kiểm tra ImageCache của Flutter — nếu hình ảnh đã được giải mã trong bộ nhớ, nó được hiển thị ngay lập tức. Khi bộ nhớ đệm không có, đĩa được kiểm tra qua flutter_cache_manager: một truy vấn SQLite kiểm tra xem tệp có tồn tại trong bộ nhớ đệm hay không và TTL của nó đã hết hạn chưa. Nếu tệp còn hiệu lực — nó được đọc từ đĩa, giải mã và hiển thị. Nếu tệp bị thiếu hoặc TTL đã hết hạn — một yêu cầu HTTP được thực hiện.

  • ImageCache — bộ nhớ đệm toàn cục của Flutter, mặc định 1000 mục / 100 MB
  • flutter_cache_manager — SQLite + hệ thống tệp, TTL 7 ngày
  • Tải xuống HTTP — thực hiện qua gói http hoặc HttpClient tùy chỉnh

Dọn dẹp bộ nhớ đệm

DefaultCacheManager cung cấp các phương thức emptyCache() (dọn dẹp hoàn toàn), cleanCache() (chỉ xóa mục đã hết hạn) và clearCacheWithAge() với ngày tùy chỉnh. ImageCache được dọn dẹp tự động khi áp lực bộ nhớ hoặc thủ công qua imageCache.clear().

Kiến trúc widget CachedNetworkImage

CachedNetworkImage được xây dựng trên sự kết hợp các widget Flutter tiêu chuẩn. Triển khai nội bộ sử dụng ImageProvider để tải bất đồng bộ và StatefulWidget để quản lý vòng đời.

Các tham số chính

imageUrl — tham số bắt buộc, URL hình ảnh (String hoặc Uri). placeholder — widget hiển thị trong khi tải. errorWidget — widget khi lỗi tải. progressIndicatorBuilder — builder nhận ngữ cảnh, URL và DownloadProgress với các trường totalSize và downloadedSize.

ImageProvider

CachedNetworkImageProvider — triển khai ImageProvider trả về CachedNetworkStreamImage, quản lý việc tải xuống và lưu đệm. Nhà cung cấp tích hợp với ImageCache của Flutter và hỗ trợ tất cả các khả năng ImageProvider tiêu chuẩn: chia tỷ lệ, căn giữa và lặp lại.

Cấu hình flutter_cache_manager

flutter_cache_manager là thư viện nền tảng cho bộ nhớ đệm của CachedNetworkImage. Nó cung cấp DefaultCacheManager với cơ sở dữ liệu SQLite đã được cấu hình, TTL và giới hạn tệp. Nếu cần, có thể tạo CacheManager tùy chỉnh với các tham số riêng.

Tham sốMô tảGiá trị mặc định
maxAgeCacheObjectThời gian lưu trữ tệp tối đa7 ngày
maxNrOfCacheObjectsSố lượng tệp tối đa200
keyĐịnh danh duy nhất của trình quản lý“default”
repoLoại lưu trữ siêu dữ liệuCacheObjectRepository (SQLite)
fileServiceHTTP client để tải xuốngHttpFileService

CacheManager tùy chỉnh được tạo bằng cách kế thừa từ CacheManager với ghi đè phương thức. Điều này hữu ích khi cần lưu trữ hình ảnh trong thư mục riêng hoặc sử dụng HTTP client khác. Instance của trình quản lý sau đó được truyền vào tham số cacheManager của CachedNetworkImage.

Cơ sở dữ liệu SQLite của DefaultCacheManager nằm trong temporaryDirectory của ứng dụng tại đường dẫn `{key}/CacheObjects.db`. Nó chứa bảng cacheObjects với các trường: key (URL), relativePath, url, creationDate, eTag, httpHeaders. Khi dọn dẹp các mục đã hết hạn, truy vấn SQL với điều kiện trên maxAgeCacheObject được sử dụng.

Ví dụ sử dụng CachedNetworkImage trong Dart

CachedNetworkImage cung cấp hai cách tiếp cận tải chính: widget CachedNetworkImage và CachedNetworkImageProvider cho các tình huống tùy chỉnh.

Tải cơ bản với placeholder

CachedNetworkImage — cách tiếp cận chính. Chỉ cần truyền imageUrl và placeholder. Widget tự động hiển thị placeholder cho đến khi tải hoàn tất và thay thế nó bằng hình ảnh.

dart
CachedNetworkImage(
    imageUrl: "https://example.com/photo.jpg",
    placeholder: (context, url) => CircularProgressIndicator(),
    errorWidget: (context, url, error) => Icon(Icons.error),
    width: 200,
    height: 200,
    fit: BoxFit.cover,
)

placeholder và errorWidget là các hàm builder nhận ngữ cảnh, URL và (đối với errorWidget) một đối tượng lỗi. Cách tiếp cận này cho phép hiển thị các placeholder khác nhau tùy theo URL hoặc loại lỗi.

Tải với tiến trình

progressIndicatorBuilder — tham số cho phép hiển thị tiến trình tải xuống dưới dạng phần trăm. DownloadProgress chứa totalSize (có thể là -1 nếu không xác định) và downloadedSize.

dart
CachedNetworkImage(
    imageUrl: "https://example.com/large.jpg",
    progressIndicatorBuilder: (context, url, downloadProgress) {
        return Center(
            child: SizedBox(
                width: 50,
                height: 50,
                child: Stack(
                    alignment: Alignment.center,
                    children: [
                        CircularProgressIndicator(
                            value: downloadProgress.progress,
                        ),
                        Text(
                            "\(downloadProgress.downloadedSize ~/ 1024) KB",
                        ),
                    ],
                ),
            ),
        };
    },
    imageBuilder: (context, imageProvider) {
        return Container(
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12),
                image: DecorationImage(
                    image: imageProvider,
                    fit: BoxFit.cover,
                ),
            ),
        };
    },
)

imageBuilder — tham số tùy chọn cho phép tùy chỉnh hiển thị hình ảnh: thêm góc bo tròn, đổ bóng, trang trí. Ví dụ sử dụng DecorationImage với BorderRadius cho các góc bo tròn.

Sử dụng CachedNetworkImageProvider

CachedNetworkImageProvider — nhà cung cấp cho Image hoặc DecorationImage mà không cần sử dụng widget CachedNetworkImage. Hữu ích khi làm việc với BoxDecoration, FadeInImage hoặc các widget Image tùy chỉnh.

dart
Container(
    decoration: BoxDecoration(
        image: DecorationImage(
            image: CachedNetworkImageProvider(
                "https://example.com/bg.jpg",
                maxWidthBytes: 2048,
                maxHeightBytes: 2048,
            ),
            fit: BoxFit.cover,
        ),
    ),
)

ImageBuilder và xử lý tùy chỉnh

Tham số imageBuilder trong CachedNetworkImage cho phép ghi đè widget Image tiêu chuẩn bằng triển khai tùy chỉnh. Thay vì hiển thị trực tiếp Image, bạn có thể sử dụng Container với trang trí, ClipRRect để cắt, hoặc Ink.image để tạo hiệu ứng gợn sóng. imageBuilder nhận ngữ cảnh và ImageProvider của hình ảnh đã sẵn sàng, cho phép kiểm soát hoàn toàn việc hiển thị.

Các tham số bổ sung: memCacheWidthmemCacheHeight giới hạn kích thước hình ảnh trong bộ nhớ đệm, giảm tải cho ImageCache của Flutter. cacheKey cho phép đặt khóa bộ nhớ đệm tùy chỉnh thay vì URL, hữu ích cho hình ảnh có mã thông báo ủy quyền trong URL (các tham số truy vấn thay đổi theo mỗi yêu cầu nhưng nội dung vẫn giữ nguyên).

CachedNetworkImage vs Image.network tiêu chuẩn

Widget Image.network tiêu chuẩn tải hình ảnh mỗi khi widget được xây dựng lại mà không lưu vào đĩa. CachedNetworkImage thêm bộ nhớ đệm tệp, chỉ báo tiến trình và xử lý lỗi, nhưng thêm phụ thuộc vào flutter_cache_manager và SQLite.

Tiêu chíImage.networkCachedNetworkImage
Bộ nhớ đệm trên đĩaKhông (chỉ bộ nhớ đệm của Flutter)Có (SQLite + tệp)
Tiến trìnhKhôngprogressIndicatorBuilder
Widget lỗiChỉ placeholder đỏ trong debugerrorWidget tùy chỉnh
TTL bộ nhớ đệmKhông áp dụngCó thể cấu hình (mặc định 7 ngày)
Phụ thuộcKhông có (tích hợp trong Flutter)cached_network_image + flutter_cache_manager + sqflite
Truy cập ngoại tuyếnKhôngCó (với tệp đã tải trước đó)
Kích thước build0 KB bổ sung~300 KB bổ sung

Đối với các dự án mà khả năng ngoại tuyến và tiết kiệm băng thông là quan trọng, CachedNetworkImage là lựa chọn rõ ràng. Đối với các màn hình đơn giản một lần (ví dụ: onboarding hoặc splash), Image.network không yêu cầu phụ thuộc bổ sung.

Thiết lập CachedNetworkImage trong dự án Flutter

CachedNetworkImage được thêm như một phụ thuộc pub.dev tiêu chuẩn. Sau khi cài đặt, widget đã sẵn sàng để sử dụng. flutter_cache_manager được bao gồm như một phụ thuộc truyền dẫn.

dart
// pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  cached_network_image: ^3.4.1

Theo mặc định, DefaultCacheManager được sử dụng với các thiết lập: TTL = 7 ngày, tối đa 200 tệp. Để thay đổi các tham số toàn cục, một instance CacheManager tùy chỉnh được tạo với Config, nơi maxAgeCacheObject, maxNrOfCacheObjects và repo được ghi đè.

dart
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';

final customCacheManager = CacheManager(
  Config(
    "custom_images",
    stalePeriod: Duration(days: 14),
    maxNrOfCacheObjects: 500,
    repo: JsonCacheInfoRepository(
      databaseName: "custom_images_cache.db",
    ),
  ),
);

// Sử dụng trình quản lý tùy chỉnh:
CachedNetworkImage(
    cacheManager: customCacheManager,
    imageUrl: url,
    // ...
)

maxWidthBytesmaxHeightBytes — các tham số tùy chọn để giới hạn kích thước tệp trong bộ nhớ đệm. Điều này hữu ích để tiết kiệm dung lượng đĩa khi hình ảnh gốc lớn hơn kích thước màn hình yêu cầu.

Câu hỏi thường gặp

CachedNetworkImage là gì và tại sao cần nó?

CachedNetworkImage là widget Flutter để tải hình ảnh từ mạng với bộ nhớ đệm tự động trên đĩa. Nó cần thiết để tiết kiệm băng thông, hoạt động ở chế độ ngoại tuyến và hiển thị tiến trình tải xuống, điều mà Image.network tiêu chuẩn không cung cấp.

Làm thế nào để thêm CachedNetworkImage vào dự án Flutter?

Thêm cached_network_image: ^3.4.1 vào phần dependencies của pubspec.yaml và chạy flutter pub get. Sau đó import gói trong tệp của bạn: import 'package:cached_network_image/cached_network_image.dart'.

Làm thế nào để thay đổi thời gian lưu trữ bộ nhớ đệm?

Tạo CacheManager tùy chỉnh với Config nơi tham số stalePeriod được chỉ định là Duration. Truyền trình quản lý đã tạo vào tham số cacheManager của widget CachedNetworkImage. Theo mặc định, các tệp được lưu trữ trong 7 ngày.

Làm thế nào để xóa bộ nhớ đệm của CachedNetworkImage?

Gọi DefaultCacheManager().emptyCache() để dọn dẹp hoàn toàn tất cả các tệp. Để chỉ xóa các tệp đã hết hạn, sử dụng cleanCache(). Trình quản lý tùy chỉnh được xóa bằng cách gọi emptyCache trên instance của nó.

CachedNetworkImage có hoạt động trên tất cả nền tảng Flutter không?

Có, CachedNetworkImage hỗ trợ Android, iOS, Web, macOS, Windows và Linux. API thống nhất đảm bảo hành vi nhất quán trên tất cả các nền tảng, và bộ nhớ đệm hoạt động thông qua flutter_cache_manager, được điều chỉnh cho từng hệ điều hành.

Tổng kết

  • CachedNetworkImage là giải pháp tiêu chuẩn cho tải hình ảnh có bộ nhớ đệm trong Flutter với hơn 4.000 lượt thích trên pub.dev.
  • Bộ nhớ đệm hai cấp (ImageCache của Flutter + tệp qua SQLite) giảm thiểu yêu cầu mạng và tăng tốc hiển thị.
  • progressIndicatorBuilder cho phép hiển thị phần trăm tải xuống cho hình ảnh lớn và kết nối chậm.
  • CacheManager tùy chỉnh cung cấp toàn quyền kiểm soát TTL, số lượng tệp và đường dẫn lưu trữ.
  • CachedNetworkImageProvider hoạt động với DecorationImage và BoxDecoration, mở rộng các trường hợp sử dụng.
  • Truy cập ngoại tuyến vào hình ảnh đã tải trước đó là lợi thế chính so với Image.network tiêu chuẩn.
  • Đa nền tảng — một cơ sở mã duy nhất hoạt động trên tất cả sáu nền tảng Flutter mà không cần thay đổi.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm