我在使用JSON XSuperObject的Firemonkey和从Web API检索的数据的Delphi XE7中的Android应用程序中遇到性能速度问题。
我的场景是一个系统排名表,在每次迭代时在运行时创建29个控件,有时候玩家的数量应该超过90个,所以对于每次迭代(90 * 27),它在运行时创建2610个控件。 在Windows平台上测试花了3秒钟,但在Android的移动平台上花了17秒。我知道它会影响应用程序的性能,但我不知道Windows和Android的加载时间的显着差异。
那么有没有办法减少加载时间或优化下面的代码以获得最佳性能?谢谢。
亲切的问候。
{Controls to create at runtime;
1 TLayout as parent of the controls (1 control).
1 TLine at bottom of TLayout to separate layouts (+1 control)
1 TPanel with a TImage for the player avatar and a TLabel for the player name (+3 controls).
1 TPanel with a TButton to display details (+2 controls).
1 TPanel with a THorzScrollBox containing 10 TLabels inside of 10 TRectangle as parent to scroll and display the points of the round (+22 controls).
Overall of 29 controls to create at runtime in each iteration.}
procedure TForm1.RankingClick(Sender: TObject);
var
JsonObjHC: ISuperObject;
JsonArrHC: ISuperArray;
JsonStrHC, URL_IRkC, Pais: String;
Retriever: TIdHTTP;
x, z: integer;
Before, After, Total: TDateTime;
begin
URL_IRkC := 'web api URL here ….';
Retriever := TIdHTTP.Create(nil);
try
JsonStrHC := Retriever.Get(URL_IRkC);
finally
Retriever.DisposeOf;
end;
JsonArrHC := SA(JsonStrHC);
Before := Time; // to check seconds before loop starts
LytMainRk.BeginUpdate; //Main layout that contains all controls.
for x := 0 to JsonArrHC.Length-1 do
begin
JsonObjHC := JsonArrHC.O[x];
// proceddure that creates controls in each iteration
Ranking_Table (JsonObjHC.S['Image'], JsonObjHC.S['Name'], JsonObjHC.I['R1'], JsonObjHC.I['R2'], JsonObjHC.I['R3'], JsonObjHC.I['R4'], JsonObjHC.I['R5'], JsonObjHC.I['R6'], JsonObjHC.I['R7'], JsonObjHC.I['R8'], JsonObjHC.I['R9'], JsonObjHC.I['R10'], x, z);
inc(z, 28);
end;
LytMainRk.EndUpdate;
Total := Before - After;
SecondsBetween(ShowMessage(DateToStr(Total)); // seconds after loop finishes, 3 secs. on Windows, 17 secs. on Android
end;
procedure TForm1.Ranking_Table(Avatar, NameP: String; R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, x, z: integer);
var
RectHC_R1, RectHC_R2, RectHC_R3, RectHC_R4, RectHC_R5, RectHC_R6, RectHC_R7, RectHC_R8, RectHC_R9, RectHC_R10: TRectangle;
PanelHC, PanelHC1, PanelHC2: TPanel;
ImageAvatarHC: TImage;
LineaHC: TLine;
LNameHC, LabelHC_R1, LabelHC_R2, LabelHC_R3, LabelHC_R4, LabelHC_R5, LabelHC_R6, LabelHC_R7, LabelHC_R8, LabelHC_R9, LabelHC_R10: TLabel;
LayoutHC: TLayout;
BotonHC: TButton;
HorzScrollBoxHC: THorzScrollBox;
begin
LayoutHC := TLayout.Create(Self);
LayoutHC.Name := 'LayoutHC' + x.ToString;
LayoutHC.Align := TAlignLayout.Top;
LayoutHC.Margins.Left := 6;
LayoutHC.Margins.Right := 6;
LayoutHC.Margins.Top := 0;
LayoutHC.Position.Y := z;
LayoutHC.Height := 28;
LayoutHC.Parent := LyHistorialC;
LineaHC := TLine.Create(Self);
LineaHC.Name := 'LineaHC' + x.ToString;
LineaHC.Align := TAlignLayout.MostBottom;
LineaHC.LineType := TLineType.Top;
LineaHC.Height := 1;
LineaHC.Stroke.Color := $FF708090;
LineaHC.Stroke.Thickness := 1;
LineaHC.Parent := LayoutHC;
PanelHC := TPanel.Create(Self);
PanelHC.Name := 'PanelHC_' + x.ToString;
PanelHC.Align := TAlignLayout.MostLeft;
PanelHC.Width := 126;
PanelHC.Parent := LayoutHC;
ImageAvatarHC := TImage.Create(Self);
ImageAvatarHC.Name := ' ImageAvatarHC ' + x.ToString;
ImageAvatarHC.Align := TAlignLAyout.Left;
ImageAvatarHC.Margins.Left := 4;
ImageAvatarHC.Margins.Right := 2;
ImageAvatarHC.Width := 28;
load_image_from_resource(ImageAvatarHC, Avatar);
ImageAvatarHC.Parent := PanelHC;
LNameHC := TLabel.Create(Self);
LNameHC.Name := ' LNameHC ' + x.ToString;
LNameHC.Align := TAlignLayout.Client;
LNameHC.Margins.Left := 2;
LNameHC.AutoSize := True;
LNameHC.TextSettings.FontColor := $FF000000;
LNameHC.TextSettings.Font.Size := 10;
LNameHC.StyledSettings := [];
LNameHC.Text := NameP;
LNameHC.Parent := PanelHC;
PanelHC1 := TPanel.Create(Self);
PanelHC1.Name := 'PanelHC1' + x.ToString;
PanelHC1.Align := TAlignLayout.Left;
PanelHC1.Width := 26;
PanelHC1.Parent := LayoutHC;
BotonHC := TButton.Create(Self);
BotonHC.Name := 'BotonHC' + x.ToString;
BotonHC.Align := TAlignLayout.Client;
BotonHC.TextSettings.Font.Style := [TFontStyle.fsBold];
BotonHC.Text := '>';
BotonHC.OnClick := ClickHistorialC;
BotonHC.Parent := PanelHC1;
PanelHC2 := TPanel.Create(Self);
PanelHC2.Name := 'PanelHC2' + x.ToString;
PanelHC2.Align := TAlignLayout.Client;
PanelHC2.Parent := LayoutHC;
HorzScrollBoxHC := THorzScrollBox.Create(Self);
HorzScrollBoxHC.Name := 'HorzScrollBoxHC' + x.ToString;
HorzScrollBoxHC.Align := TAlignLayout.Client;
HorzScrollBoxHC.ShowScrollBars := False;
HorzScrollBoxHC.Parent := PanelHC2;
RectHC_R1 := TRectangle.Create(Self);
RectHC_R1.Name := 'RectHC_R1' + x.ToString;
RectHC_R1.Align := TAlignLayout.Left;
RectHC_R1.Fill.Color := $FF1E90FF;
RectHC_R1.Margins.Bottom := 2;
RectHC_R1.Margins.Left := 2;
RectHC_R1.Margins.Top := 2;
RectHC_R1.Sides := [];
RectHC_R1.Stroke.Kind := TBrushKind.None;
RectHC_R1.Width := 23;
RectHC_R1.XRadius := 4;
RectHC_R1.YRadius := 4;
RectHC_R1.Parent := HorzScrollBoxHC;
LabelHC_R1 := TLabel.Create(Self);
LabelHC_R1.Name := ' LabelHC_R1' + x.ToString;
LabelHC_R1.Align := TAlignLayout.Client;
LabelHC_R1.AutoSize := True;
LabelHC_R1.TextSettings.FontColor := $FFFFFFFF;
LabelHC_R1.TextSettings.Font.Size := 11;
LabelHC_R1.TextSettings.HorzAlign := TTextAlign.Center;
LabelHC_R1.StyledSettings := [];
LabelHC_R1.Text := R1.ToString;
LabelHC_R1.Parent := RectHC_R1;
{ ………………….
Up to 8 TRectangles and TLabels to create here…
……………………. }
RectHC_R10 := TRectangle.Create(Self);
RectHC_R10.Name := 'RectHC_R10' + x.ToString;
RectHC_R10.Align := TAlignLayout.Left;
RectHC_R10.Fill.Color := $FF1E90FF;
RectHC_R10.Margins.Bottom := 2;
RectHC_R10.Margins.Left := 2;
RectHC_R10.Margins.Top := 2;
RectHC_R10.Sides := [];
RectHC_R10.Stroke.Kind := TBrushKind.None;
RectHC_R10.Width := 23;
RectHC_R10.XRadius := 4;
RectHC_R10.YRadius := 4;
RectHC_R10.Parent := HorzScrollBoxHC;
LabelHC_R10 := TLabel.Create(Self);
LabelHC_R10.Name := ' LabelHC_R10' + x.ToString;
LabelHC_R10.Align := TAlignLayout.Client;
LabelHC_R10.AutoSize := True;
LabelHC_R10.TextSettings.FontColor := $FFFFFFFF;
LabelHC_R10.TextSettings.Font.Size := 11;
LabelHC_R10.TextSettings.HorzAlign := TTextAlign.Center;
LabelHC_R10.StyledSettings := [];
LabelHC_R10.Text := R10.ToString;
LabelHC_R10.Parent := RectHC_R1;
end;
答案 0 :(得分:0)
使用那么多控件永远无法获得可接受的速度,尤其是在移动设备上。
对于矩形,文字,线条......我只是使用自定义绘画。您可以使用带有OnPaint
事件的PaintBox。
procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
Canvas.Fill.Color := $FF1E90FF;
Canvas.FillRect(RectF(10, 10, 200, 50), 4, 4, [], 1.0);
Canvas.Fill.Color := $FFFFFFFF;
Canvas.Font.Size := 13.0;
Canvas.FillText(RectF(10, 10, 200, 50), 'My Text', True, 1.0, [], TTextAlign.Center, TTextAlign.Center);
end;
只要需要更新屏幕,就会调用此事件。如果您的数据已更改并且您想要更新屏幕,请致电PaintBox1.InvalidateRect({...area that needs to be updated});
。这将触发屏幕更新。
按钮有点棘手,您必须使用OnMouseDown和OnMouseUp事件并手动评估鼠标点击次数。
从长远来看,拥有自己的控件可能是有意义的,该控件源自TControl
或TStyledControl
,它使用重写的Paint
方法进行绘制。