我最近开始使用动态列表视图项目。除了当我尝试使用位图添加和清除项目时,它很棒。我有一个列表视图,我在其中添加项目并将图像下载到 memstream 中并将其分配给动态列表视图项目的位图。这有效,除了当我用 lv.items.clear 清除所有项目时,它不会从内存中删除。
即使我清除了旧项目,内存仍在不断增加。有没有办法清除所有位图?
基本上发生的事情是:
- 用 10 个项目填充动态列表视图。添加数据和位图。
- 看记忆。增加了 2 兆字节。
- 使用 lv.items.clear 清除列表视图。
- 看记忆。不用找了?
- 重复,记忆就会不断上升。
我尝试遍历所有列表视图项并将每个位图设置为nil
但没有导致任何内存更改。我还尝试通过循环释放每个项目,但它只会使应用程序崩溃。
我应该以某种方式清除所有项目或位图吗?如果是这样,我该怎么做呢?
这是我加载所有项目的方式:
procedure TPluginInstaller.Load;
begin
with frmMain.framePluginManager do
begin
TThread.CreateAnonymousThread(
procedure
begin
var restClient := TRESTClient.Create(nil);
var restRequest := TRESTRequest.Create(nil);
var restResponse := TRESTResponse.Create(nil);
try
restRequest.Client := restClient;
restRequest.Response := restResponse;
restClient.BaseURL := BASE_URL;
restClient.UserAgent := APP_USERAGENT;
restRequest.AddParameter('query', fQuery);
restRequest.AddParameter('page', fPage.ToString);
restRequest.AddParameter('sort', SortBy[fSort]);
if fSort = 0 then
restRequest.AddParameter('sortdir', 'asc')
else
restRequest.AddParameter('sortdir', 'desc');
restRequest.AddParameter('categories[]', 'rust');
restRequest.Execute;
var jdata := restResponse.JSONValue;
fLastPage := jdata.GetValue<Integer>('last_page', 1);
fPage := jdata.GetValue<Integer>('current_page', 1);
TThread.Synchronize(nil,
procedure
begin
spnedtPage.Max := fLastPage;
spnedtPage.Value := fPage;
lblPageMax.Text := ' of ' + fLastPage.ToString;
lvPluginInstaller.BeginUpdate;
try
lvPluginInstaller.Items.Clear;
for var jplugins in (jdata.FindValue('data') as TJSONArray) do
begin
var aItem := lvPluginInstaller.Items.Add;
var aIcon := aItem.Objects.FindObjectT<TListItemImage>('Icon');
var aDownloadsIcon := aItem.Objects.FindObjectT<TListItemImage>('DownloadsIcon');
var aVersionIcon := aItem.Objects.FindObjectT<TListItemImage>('VersionIcon');
var aAuthorIcon := aItem.Objects.FindObjectT<TListItemImage>('AuthorIcon');
var aUpdatedIcon := aItem.Objects.FindObjectT<TListItemImage>('UpdatedIcon');
var aTitle := aItem.Objects.FindObjectT<TListItemText>('Title');
var aDescription := aItem.Objects.FindObjectT<TListItemText>('Description');
var aVersion := aItem.Objects.FindObjectT<TListItemText>('Version');
var aDownloads := aItem.Objects.FindObjectT<TListItemText>('Downloads');
var aAuthor := aItem.Objects.FindObjectT<TListItemText>('Author');
var aURL := aItem.Objects.FindObjectT<TListItemText>('URL');
var aUpdated := aItem.Objects.FindObjectT<TListItemText>('Updated');
GetIcon(jplugins.GetValue<string>('icon_url').Trim, aIcon);
aDownloadsIcon.ImageIndex := 0;
aVersionIcon.ImageIndex := 1;
aAuthorIcon.ImageIndex := 2;
aUpdatedIcon.ImageIndex := 4;
aTitle.Text := jplugins.GetValue<string>('title', 'Unknown Plugin Title');
aDescription.Text := jplugins.GetValue<string>('description', 'Unknown Plugin Description');
aVersion.Text := jplugins.GetValue<string>('latest_release_version_formatted', 'Unknown Version');
aDownloads.Text := jplugins.GetValue<string>('downloads_shortened', 'Unknown Downloads');
aAuthor.Text := jplugins.GetValue<string>('author', 'Unknown Author');
aURL.Text := jplugins.GetValue<string>('json_url', 'Unknown URL');
aUpdated.Text := jplugins.GetValue<string>('latest_release_at', 'Unknown');
end;
finally
lvPluginInstaller.EndUpdate;
end;
end);
finally
restResponse.Free;
restRequest.Free;
restClient.Free;
end;
end).Start;
end;
end;
从 url 加载位图:
procedure TPluginInstaller.GetIcon(const aURL: string; aIcon: TListItemImage);
begin
if aURL = '' then
begin
aIcon.ImageIndex := 3;
Exit;
end;
TThread.CreateAnonymousThread(
procedure
begin
var imgStream := TMemoryStream.Create;
try
TDownloadURL.DownloadRawBytes(aURL, imgStream);
TThread.Synchronize(nil,
procedure
begin
aIcon.Bitmap := TBitmap.CreateFromStream(imgStream);
end);
finally
imgStream.Free;
end;
end).Start;
end;