返回

Flutter实现闲鱼"同款"图片下载功能

Android

在混合开发Flutter应用中,图片下载是一个常见的需求。然而,Flutter本身并没有提供直接的图片下载功能,这给开发人员带来了额外的挑战。最近,闲鱼团队开发了一套基于外接纹理的图片下载解决方案,本文将详细介绍如何实现这一功能。

外接纹理简介

外接纹理是Flutter中用于访问原生平台图像数据的API。它允许Flutter应用程序与原生平台共享纹理,从而实现高效的图像渲染和避免内存复制。

实现图片下载功能

要实现基于外接纹理的图片下载功能,需要完成以下步骤:

  1. 创建Android平台侧代码 :在Android平台侧,需要创建用于下载和加载图片的Java代码。此代码应包括用于下载图片、将其加载到纹理中以及通知Flutter应用程序图片已加载的逻辑。
  2. 创建iOS平台侧代码 :类似于Android平台,在iOS平台侧也需要创建用于下载和加载图片的Swift代码。
  3. 在Flutter应用程序中使用 :在Flutter应用程序中,需要使用Texture小部件来显示由外接纹理提供的图像。此小部件允许您将原生纹理与Flutter UI集成。

代码示例

以下是用于实现图片下载功能的Android和iOS平台代码示例:

Android (Java):

public class ImageDownloader {

    private Context context;

    public ImageDownloader(Context context) {
        this.context = context;
    }

    public void downloadImage(String url, TextureRegistry textureRegistry) {
        // 使用Glide下载图片
        Glide.with(context)
                .load(url)
                .into(new SimpleTarget<Drawable>() {
                    @Override
                    public void onResourceReady(@NonNull Drawable drawable, @Nullable Transition<? super Drawable> transition) {
                        // 将Drawable加载到纹理中
                        SurfaceTexture surfaceTexture = textureRegistry.createSurfaceTexture();
                        Canvas canvas = surfaceTexture.lockCanvas(null);
                        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                        drawable.draw(canvas);
                        surfaceTexture.unlockCanvasAndPost(canvas);

                        // 通知Flutter应用程序图片已加载
                        PlatformChannel.publish("imageLoaded", surfaceTexture.getId());
                    }
                });
    }
}

iOS (Swift):

import UIKit
import Flutter

class ImageDownloader: NSObject {

    private let context: FlutterViewController

    init(context: FlutterViewController) {
        self.context = context
    }

    func downloadImage(url: String, textureRegistry: FlutterTextureRegistry) {
        // 使用SDWebImage下载图片
        SDWebImageManager.shared.loadImage(with: URL(string: url), options: [], progress: nil, completed: { [weak self] (image, data, error, cacheType, finished, url) in
            guard let strongSelf = self else { return }

            // 将图片加载到纹理中
            let texture = textureRegistry.createTexture(from: image)

            // 通知Flutter应用程序图片已加载
            strongSelf.context.engine.sendWindow(channel: "imageLoaded", message: ["textureId": texture.id])
        })
    }
}

总结

使用外接纹理,可以轻松地在Flutter应用程序中实现高效的图片下载功能。通过这种方法,Flutter应用程序可以与原生平台共享图像纹理,从而避免内存复制并提高性能。本文提供的代码示例可作为实现这一功能的参考。