IOS下一个异步加载图像的类
IPhone上手机性能不佳,批量加载网络图像时很慢,所以写了一个异步加载图像的类.
有待进一步实现的功能是图像的硬盘cache.
unit FMX.AsyncImage.IOS;
interface
uses FMX.Types,FMX.Graphics,System.Types, System.Generics.Collections, iOSapi.Foundation, Macapi.ObjectiveC, iOSapi.UIKit;
type
NSURLConnectionDelegate = interface(IObjectiveC)
['{682BABAC-89E0-4A9B-BFF5-96A7EE7881A6}']
end;
NSURLConnectionDataDelegate = interface(NSURLConnectionDelegate)
['{6F015871-FCF4-4F8D-B9E5-C6484D6F60E7}']
procedure connection(connection: NSURLConnection; didReceiveData: NSData); cdecl;
procedure connectionDidFinishLoading(connection: NSURLConnection); cdecl;
end;
TAsyncImageReqeust = class(TOCLocal, NSURLConnectionDataDelegate)
private
FBitmap:TBitmap;
FConnection:NSURLConnection;
FData:NSMutableData;
protected
public
constructor Create(ABitmap:TBitmap;AUrl:string);
destructor Destroy;override;
procedure Cancel;
procedure connection(connection: NSURLConnection; didReceiveData: NSData); cdecl;
procedure connectionDidFinishLoading(connection: NSURLConnection); cdecl;
end;
TAsyncImageLoader=class
private
FRequestMap:TDictionary
public
constructor Create;
destructor Destroy;override;
procedure Request(AUrl:string;ABitmap:TBitmap);
procedure Cancel(ABitmap:TBitmap);
procedure CancelAll;
end;
implementation
uses System.Math, FMX.Types3D, iOSapi.CoreGraphics, System.IOUtils, System.SysUtils, System.Classes;
{ TAsyncImageLoader }
procedure TAsyncImageLoader.Cancel(ABitmap: TBitmap);
var
request: TAsyncImageReqeust;
begin
if not FRequestMap.ContainsKey(ABitmap) then
Exit;
request:=FRequestMap[ABitmap];
request.Cancel;
end;
procedure TAsyncImageLoader.CancelAll;
var
request:TAsyncImageReqeust;
begin
for request in FRequestMap.Values do
begin
Request.cancel;
end;
end;
constructor TAsyncImageLoader.Create;
begin
FRequestMap:=TDictionary
end;
destructor TAsyncImageLoader.Destroy;
begin
CancelAll;
FRequestMap.Free;
inherited;
end;
procedure TAsyncImageLoader.Request(AUrl: string; ABitmap: TBitmap);
begin
if FRequestMap.ContainsKey(ABitmap) then
Exit;
FRequestMap.Add(ABitmap, TAsyncImageReqeust.Create(ABitmap, AUrl));
end;
{ TAsyncImageReqeust }
procedure TAsyncImageReqeust.Cancel;
begin
FConnection.cancel;
end;
procedure TAsyncImageReqeust.connection(connection: NSURLConnection;
didReceiveData: NSData);
begin
FData.appendData(didReceiveData);
end;
procedure TAsyncImageReqeust.connectionDidFinishLoading(
connection: NSURLConnection);
var
stream:TMemoryStream;
begin
stream:=TMemoryStream.Create;
try
stream.Write(FData.bytes^, Fdata.length);
stream.position:=0;
FBitmap.LoadFromStream(stream);
finally
stream.free;
end;
end;
constructor TAsyncImageReqeust.Create(ABitmap: TBitmap; AUrl: string);
var
url:NSURL;
request:NSURLRequest;
begin
inherited Create;
FBitmap:=ABitmap;
url:=TNSURL.Wrap(TNSURL.OCClass.URLWithString(NSSTR(Aurl)));
request:=TNSURLRequest.Wrap(TNSURLRequest.OCClass.requestWithURL(url, NSURLRequestUseProtocolCachePolicy, 60));
FConnection:=TNSURLConnection.Create;
FConnection.initWithRequest(request, Self.GetObjectID);
FData:=TNSMutableData.Create;
end;
destructor TAsyncImageReqeust.Destroy;
begin
FConnection.cancel;
FConnection.release;
FData.release;
inherited;
end;
end.