Hallo,
ich weiß, dass ich diese Thema schon hier hatte:
http://www.delphipraxis.net/188412-a...-neustart.html
Da ich bei diesem Thread allerdings zu Anfang den Fehler noch nicht so gut eingrenzen konnte und auch irgendwie mein Code aus dem Thread verschwunden ist (zumindest sehe ich ihn nicht mehr) dacht ich, ich fasse meine Problematik hier nochmal zusammen.
Unten findet ihr ein Beispiel (gesamte
Unit). Diese veranschaulicht nur den Fehler und macht sonst keinen Sinn...
Im Prinzip habe ich eine Task, die immer wieder ein Bild als Byte-Stream liefert (z.B. aus der
DB). Sobald es geladen ist, wird es durch TThread.Queue() an den Haupt-Thread gegeben und in der
GUI angezeigt.
Wird während des Ladens (mehrere Bilder) die App mit dem Home-Button in den Hintergrund gelegt, so hängt sie sich auf, wenn ich sie wieder in den Vordergrund holen will. Das kann ich nur bei Android nachvollziehen. (Delphi 10, getestet mit Android 4.1 und Android 5.1)
Mit meinem Beispielcode bekommt man das auch eindeutig hin (nach Start der Task einfach mal in den Hintergrund legen und wieder öffnen).... habe ich ein grundsätzliches Problem beim Handling oder ist das ein Bug in Bezug auf die Android-Platform?
Bin für jeden Tip sehr dankbar. Da es in meinen Apps ein absolut nachvollziehbares Problem ist, würde ich da gerne eine Lösung finden.
Delphi-Quellcode:
type
TBinaryData = TArray<Byte>;
TFrmMain =
class(TForm)
Button1: TButton;
imgAlbert: TImage;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
FTask: ITask;
FData: TBinaryData;
procedure ProcessBitmap(
const AData: TBinaryData);
end;
var
FrmMain: TFrmMain;
implementation
{$R *.fmx}
procedure TFrmMain.FormCreate(Sender: TObject);
var
MS: TMemoryStream;
begin
MS := TMemoryStream.Create;
try
//Bild nur dummy in der Form, so dass die Daten in ein Byte-Array geladen werden können
imgAlbert.Bitmap.SaveToStream(MS);
MS.Position := 0;
SetLength(FData,MS.Size);
MS.
Read(FData[0],MS.Size);
finally
MS.DisposeOf;
MS :=
nil;
end;
end;
procedure TFrmMain.Button1Click(Sender: TObject);
begin
if Assigned(FTask)
then
begin
FTask.Cancel;
FTask :=
nil;
Button1.Text := '
Start Task';
end else
begin
FTask := TTask.Run(
procedure
var
CopyOfData: TBinaryData;
begin
while true
do
begin
CopyOfData := Copy(FData);
//FData muss natürlich abgesichert werden - passt aber für Beispiel. Ist ja nur ein Thread.
TThread.Queue(
nil,
procedure
begin
ProcessBitmap(CopyOfData);
end);
Sleep(100);
end;
end);
Button1.Text := '
Stop Task';
end;
end;
procedure TFrmMain.ProcessBitmap(
const AData: TBinaryData);
var
Bitmap: TBitmap;
MS: TMemoryStream;
begin
Bitmap := TBitmap.Create;
MS := TMemoryStream.Create;
try
MS.Position := 0;
MS.
Write(AData[0],Length(AData));
MS.Position := 0;
{ !!!!! Mit dieser Zeile: FEHlER ! - sonst läuft es !!!! }
Bitmap.LoadFromStream(MS);
//jetzt normalerweise Bild in der GUI anzeigen... ist aber nicht die Fehlerursache
finally
MS.DisposeOf;
MS :=
nil;
Bitmap.DisposeOf;
Bitmap :=
nil;
end;
end;
end.