Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Android App blockiert bei Aufruf aus Hintergrund (https://www.delphipraxis.net/188851-android-app-blockiert-bei-aufruf-aus-hintergrund.html)

AndyDF 13. Apr 2016 15:16

Android App blockiert bei Aufruf aus Hintergrund
 
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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz