Delphi FMX: HTTPClient асинхронный пост работает в Windows, сбои в Android - PullRequest
0 голосов
/ 24 февраля 2019

Я использую THTTPClient в Delphi 10.3 для выполнения операции POST и получения данных с сервера.Параметры в формате JSON.Проблема:

  • При компиляции как Win32 приложение прекрасно работает как при выполнении асинхронного вызова, так и без него.
  • При компиляции как Android приложение, оно не работает в асинхронном вызове и нормально работает в обычном режиме.

Ошибка сбоя указывает на то, что запрос как-то не передает параметры json (что происходит только в асинхронном режиме).Режим). Например: если удаленному серверу требуется передать два параметра (скажем, имя и возраст), я получу удаленную ошибку «имя является обязательным полем».

Мой кодоснованный на образце загрузки Delphi.Что-то, что я должен изменить, чтобы это работало в Android?Спасибо!

Вот соответствующий код:

//the content  of mmoParams.Text is a JSON string:
//{"name":"somebody","salary":"1000","age":"51"}

Params := TStringStream.Create(mmoParams.Text, TEncoding.UTF8);
Params.Position := 0;
// prepare the request
HTTPClient.ContentType := 'application/json';
HTTPClient.Accept      := 'application/json';
if chkAsync.IsChecked then begin
    // prepare the request
    HTTPClient.ContentType := 'application/json';
    HTTPClient.Accept      := 'application/json';
    // make the request and handle in the callback
    HTTPResult:= HTTPClient.BeginPost(DoEndPost,edtURL.Text,Params);
end
else begin
    // make the request
    HTTPResponse       := HTTPClient.Post(edtURL.Text,Params);
    // handle response
    lblStatusCode.Text := HTTPResponse.StatusCode.ToString;
    mmoResult.Text     := HTTPResponse.ContentAsString(TEncoding.UTF8);
end;

и вот процедура обратного вызова, когда выполняется асинхронный вызов (BeginPost).

procedure TMainForm.DoEndPost(const AsyncResult: IAsyncResult);

begin
  try
    HTTPResponse := THTTPClient.EndAsyncHTTP(AsyncResult);
    TThread.Synchronize(nil,
      procedure
      begin
          // handle result
         lblStatusCode.Text := HTTPResponse.StatusCode.ToString;
         mmoResult.Text     := HTTPResponse.ContentAsString(TEncoding.UTF8);
      end);
  finally
  end;
end;

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019

Просто скопируйте файлы из {$ BDS} / source / rtl / net из 10.2.3 в каталог вашего проекта и отрежьте всю несуществующую функцию GetEncodingMIMEName в utf-8.Это исправление работает отлично, но будет лучше, если Embarcadero прекратит делать глупые ошибки с каждым выпуском

0 голосов
/ 04 марта 2019

Как и предполагал @DaveNottage, анонимная тема со стандартным постом была моим лучшим решением до сих пор.До сих пор я успешно использовал эту функцию.

Я вызываю ее из основной программы с URL-адресом назначения, параметрами, которые будут отправлены в виде JSON, и процедурой обратного вызова, которая будет обрабатывать полученный HTTPResponse.,

procedure HTTPPostAsync(HTTPClient: TNetHTTPClient; url, params: string; CallBack: HTTPClientProc);

var
  Thread: TThread;

begin

  // define the thread
  Thread := TThread.CreateAnonymousThread (
      procedure
      var
          HTTPResponse: IHTTPResponse;
          JSon        : TStringStream;
      begin
            Json   := TStringStream.Create(Params, TEncoding.UTF8);
            Json.Position := 0;

            HTTPClient.ContentType := 'application/json';
            HTTPClient.Accept      := 'application/json';
            HTTPClient.ConnectionTimeout := 20000;
            HTTPClient.ResponseTimeout   := 20000;
            try
                HTTPResponse:= HTTPClient.Post(url,Json);
                TThread.Synchronize (TThread.CurrentThread,
                    procedure
                    begin
                        Callback(HTTPResponse);
                    end
                );
            finally
                Json.Free;
            end;
      end
  );

  // let it roll
  Thread.start;
end;
...