Search code examples
firemonkeydelphi-10.1-berlin

firemonkey threading on android show a black page


i used a httpd to request some data from internet

function requestToServer(lParamList: TStringList) : string;
var
  userDataString : string;
  lHTTP: TIdHTTP;
  serverResponce : string;
  aobj: ISuperObject;
begin
application.ProcessMessages;
  TThread.CreateAnonymousThread(
    procedure
    begin
        lHTTP := TIdHTTP.Create(nil);
        try
          serverResponce := lHTTP.Post('http://domain.com/mjson.php', lParamList);
          application.ProcessMessages;
          aobj:= SO(serverResponce);
          try
             X := aobj['dta'].AsArray;
          Except
            form2.Memo1.Lines.Add('errr');
          end;
            if aobj['result'].AsString = 'lr_102' then
            begin
             form2.Label3.Text:='Saved token expired.';
             form2.Rectangle2.Visible:=true;
            end
            else if aobj['result'].AsString = 'lr_103' then
            begin
             form2.Label3.Text:='Auto login.';
             //load device data
             form2.allDeviceListData := X;
             form2.Hide;
             form1.show;
            end;
           // globalReachedServer:=true;
        finally
          lHTTP.Free;
          lParamList.Free;
        end;

      TThread.Synchronize(nil,
        procedure
        begin

        end);
    end
  ).Start();
end;

but after reach this function the application show a black page and dont do anything until manually close

how can i do a web request at the background and with out hanging on fire-monkey !? what a bout using REST is it better to access web service's?


Solution

  • Your code is not thread-safe. Your thread is directly accessing UI controls without synchronizing with the main UI thread. That alone can cause problems.

    Also, all of the variables declared in the var section of requestToServer() should be moved into the var section of the anonymous procedure instead, since requestToServer() does not use them, so they can be completely local to the thread instead. The only thing the anonymous procedure should be capturing is the lParamList content.

    Try something more like this:

    function requestToServer(lParamList: TStringList) : string;
    var
      Params: TStringList;
      Thread: TThread;
    begin
      Params := TStringList.Create;
      try
        Params.Assign(lParamList);
      except
        Params.Free;
        raise;
      end;
      TThread.CreateAnonymousThread(
        procedure
        var
          lHTTP: TIdHTTP;
          serverResponce : string;
          aObj: ISuperObject;
        begin
          try
            try
              lHTTP := TIdHTTP.Create(nil);
              try
                serverResponce := lHTTP.Post('http://domain.com/mjson.php', lParamList);
                aObj := SO(serverResponce);
                if aObj['result'].AsString = 'lr_102' then
                begin
                  TThread.Queue(nil,
                    procedure
                    begin
                      form2.Label3.Text := 'Saved token expired.';
                      form2.Rectangle2.Visible := true;
                    end
                  );
                end
                else if aObj['result'].AsString = 'lr_103' then
                begin
                  X := aObj['dta'].AsArray;
                  TThread.Queue(nil,
                    procedure
                    begin
                      form2.Label3.Text := 'Auto login.';
                      //load device data
                      form2.allDeviceListData := X;
                      form2.Hide;
                      form1.show;
                    end
                  );
                end;
                // globalReachedServer := true;
              finally
                lHTTP.Free;
              end;
            finally
              Params.Free;
            end;
          except
            TThread.Queue(nil,
              procedure
              begin
                form2.Memo1.Lines.Add('errr');
              end
            );
          end;
        end
      ).Start;
    end;