Перейти к содержанию
Fire Monkey от А до Я
  • 0

TidHTTP не работает в Android 6


Евгений Корепов

Вопрос

TidHTTPClient перестал работать в Android 6. При попытке Get приложение закрывается с segmentation fault. То же самое приложение на всех остальных версиях андроида работает нормально.

 

На эмуляторе проверить не удалось, по какой то причине эмулятор с андроид 6 у меня запускается около часа, а попытка отладки приводит к зависанию дельфи.

 

Взял на пол часа живое устройство, отладка показала что крах происходит на стадии разбора результата. Т.е. данные с сервера реально получает (это подтверджают логи сервера), и при попытке вернуть результат все умирает. Код простой:

Var HTTPResult : TStringStream;
    URI: TIdURI;
    HTTP: TIdHTTP;
begin
  AURL:='http://10.10.0.1';
  FHost:='10.0.0.1';
  HTTP:=TIdHTTP.Create;
  HTTP.CookieManager := TIdCookieManager.Create(HTTP);
  HTTP.Request.Host:=FHost;
  HTTP.AllowCookies := true;
  HTTP.HandleRedirects := True;
  HTTP.ConnectTimeout:=6000;
  HTTP.ReadTimeout:=30000;
  HTTP.Request.CustomHeaders.AddValue('Connection','keep-alive');
  HTTP.Request.Accept:='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
  HTTP.Request.UserAgent:='Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36';
  HTTP.Request.AcceptEncoding:='gzip, deflate, sdch';
  HTTP.Request.AcceptLanguage:='ru,en-US;q=0.8,en;q=0.6';
  Result.Status:=False;
  Result.MessageText:='';
  AURL:=StringReplace(AURL,'{AuthorizationKey}',AuthorizationKey,[]);
  AURL:=StringReplace(AURL,'{Host}',FHost,[]);
  HTTPResult:= TStringStream.Create('', TEncoding.UTF8);
  URI := TIdURI.Create(AURL);
  HTTP.CookieManager.AddServerCookie(CookieAuthorization, URI);
  try
    HTTP.Get(AURL,HTTPResult);
  except
    on E : Exception do
    begin
      Result.Status:=False;
      Result.MessageText:=E.Message;
      Exit;
    end;
  end;
  Result.Status:=True;
  Result.MessageText:=Trim(HTTPResult.DataString);
  HTTPResult.Free;
  URI. Free;
end;

Падает на строке HTTP.Get(AURL,HTTPResult);, try не срабатывает. Запрос именно http, не https.

 

К сожалению живое устройство было у меня не долго, досконально разобраться не успел.

Выяснил что падает на строке 1423 в idHTTP.pas:

          IOHandler.ReadStream(LS, -1, True);

 

У кого будут какие мысли? Понятно что разработчики забили на Indy довольно давно, но не хочется целиком десяток проектов переписывать.

 

P.S. System.Net.HTTPClient работает в тех же условиях, не падает, но не смог заставить работать cookie, разбираюсь в чем дело. Хотя при отсутствии таймаутов и обработки редиректов применение сего очень ограничено.

 

 

Ссылка на комментарий

Рекомендуемые сообщения

  • 1

Возможно решить эту проблему быстро получиться на форуме разработчиков Indy. Там отвечает главный разработчик Indy c ником rlebeau:

http://forums2.atozed.com/viewforum.php?f=7&sid=a9161a8b8a29c0b7bf5428b7563111d2

Ссылка на комментарий
  • 0
  • Модераторы

у меня нормально все работает, Nexus 5, Android 6.0

с https да проблемы

 

UPDATE: Delphi Seattle

Изменено пользователем ZuBy
Ссылка на комментарий
  • 0

Евгений, под андроидом секция try except несколько иначе работает, чем под windows.. поэтому и не перехватывает ошибку. Вызов этой своей процедуры заверни в try except и там уже лови ошибку.

Ссылка на комментарий
  • 0

Евгений, под андроидом секция try except несколько иначе работает, чем под windows..

Nik, можно ссылку - где почитать про отличия? Пока работаю только с iOS, там все как привык, но скоро грядет и андроид, посему знать надо.

Ссылка на комментарий
  • 0

Nik, можно ссылку - где почитать про отличия? Пока работаю только с iOS, там все как привык, но скоро грядет и андроид, посему знать надо.

http://docwiki.embarcadero.com/RADStudio/XE5/en/Migrating_Delphi_Code_to_Mobile_from_Desktop

Изменено пользователем Nik
Ссылка на комментарий
  • 0

Евгений, под андроидом секция try except несколько иначе работает, чем под windows.. поэтому и не перехватывает ошибку. Вызов этой своей процедуры заверни в try except и там уже лови ошибку.

Т.е. если у меня не идет перехват исключения какой то функции, то ее надо завернуть еще в одну функцию и ее вызов завернуть в try except? Это как то звучит на грани безумия. В приведенной вам ссылке ничего подобного не увидел.

Но вернемся к теме, мне не нужен перехват исключения, мне нужен рабочий код. В коде ошибок нет, он работает под всеми платформами и на всех версиях кроме андроида 6.

Ссылка на комментарий
  • 0
В 11/12/2015в15:03, ZuBy сказал:

у меня нормально все работает, Nexus 5, Android 6.0

с https да проблемы

 

UPDATE: Delphi Seattle

Вот именно на нексусе с шестым андроидом я и тестил. Не могли бы вы попробовать именно Get с чтением в TStringStream? Потому как крах наступает при записи полученных данных в stream в недрах Indy. Буду безмерно благодарен. Могу завтра собрать тестовый проект для пробы.

Ссылка на комментарий
  • 0

Возможно решить эту проблему быстро получиться на форуме разработчиков Indy. Там отвечает главный разработчик Indy c ником rlebeau:

http://forums2.atozed.com/viewforum.php?f=7&sid=a9161a8b8a29c0b7bf5428b7563111d2

К сожалению на английском я только чтец, но никак не писец. ;-) Но все равно спасибо за совет.

Ссылка на комментарий
  • 0

Т.е. если у меня не идет перехват исключения какой то функции, то ее надо завернуть еще в одну функцию и ее вызов завернуть в try except? Это как то звучит на грани безумия. В приведенной вам ссылке ничего подобного не увидел.

 

Но вернемся к теме, мне не нужен перехват исключения, мне нужен рабочий код. В коде ошибок нет, он работает под всеми платформами и на всех версиях кроме андроида 6.

 

Да, именно так.. А не увидел - просто невнимательно смотрел ) http://docwiki.embarcadero.com/RADStudio/XE5/en/Migrating_Delphi_Code_to_Mobile_from_Desktop#Use_a_Function_Call_in_a_try-except_Block_to_Prevent_Uncaught_Hardware_Exceptions

 

var
  P: ^Integer = nil;
 
procedure G1;
begin
  P^ := 42;
end;
 
begin
  try
    G1;
  except
    writeln('Catch:G1 - pass');
  end;
end.

По поводу андроида 6 - вечером на планшете обновился до этой версии.. Но я Post использую в своей программе.. Проверю завтра как будет работать..

Тестовый проект выкладывай - попробуем разобраться.

 

Ссылка на комментарий
  • 0
  • Модераторы

 

у меня нормально все работает, Nexus 5, Android 6.0

с https да проблемы

 

UPDATE: Delphi Seattle

Вот именно на нексусе с шестым андроидом я и тестил. Не могли бы вы попробовать именно Get с чтением в TStringStream? Потому как крах наступает при записи полученных данных в stream в недрах Indy. Буду безмерно благодарен. Могу завтра собрать тестовый проект для пробы.

 

давайте проект, протестю

 

 

на счёт Exception нужно использовать EidException для отлова

try
except 
   on E: EIdException do
end;

посмотрите ошибку, что отлавливается

Ссылка на комментарий
  • 0

под андроидом секция try except несколько иначе работает, чем под windows.. поэтому и не перехватывает ошибку. Вызов этой своей процедуры заверни в try except и там уже лови ошибку.

Продолжая про отличия try-except под андроид.

 

1. В хелпе по приведенной вами ссылке написано - должен быть вызов хотя бы одной процедуры/метода, дальше расписано, что это должен быть не инлайн-метод.

2. Post в idHTTP не inline, и это метод, условие срабатывания except-блока (по хелпу) соблюдено.

3. В except-блоке должны перехватываться все исключения, т.к. там написано on e: Exception do.

 

Где в моих рассуждениях ошибка?

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...