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

TThread.ForceQueue не работает в Android

Вопросы

TThread.ForceQueue не работает в Android. Но можно утешить себя тем, что отлично работает в Windows ;-)

Код следующий:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Memo,
  FMX.Controls.Presentation, FMX.ScrollBox;

type
  TForm1 = class(TForm)
    Memo: TMemo;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure MyLog(AMessage : String);
    procedure TestForceQueue;
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.TestForceQueue;
begin
  MyLog('In main thread start');
  TThread.ForceQueue(Nil,
    procedure
    begin
      MyLog('In ForceQueue start');
      TThread.Sleep(2000);
      MyLog('In ForceQueue stop');
    end);
  MyLog('In main thread stop');
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  TestForceQueue;
end;

procedure TForm1.MyLog(AMessage : String);
Var ATime : String;
    LMessage : String;
begin
  DateTimeToString(ATime, 'dd.mm.yyyy hh.nn.ss.zzz', Now);
  LMessage:=ATime + ' ' + AMessage;
  TThread.Synchronize(Nil,
    procedure
    begin
      Memo.Lines.Add(LMessage);
    end);
end;

end.

В Windows все работает как ожидается:

Цитата

13.04.2017 16.08.17.028 In main thread start
13.04.2017 16.08.17.028 In main thread stop
13.04.2017 16.08.17.028 In ForceQueue start
13.04.2017 16.08.19.029 In ForceQueue stop

В андроиде ситуация следующая:

Цитата

13.04.2017 16.06.58.554 In main thread start
13.04.2017 16.06.58.580 In ForceQueue start
13.04.2017 16.07.00.586 In ForceQueue stop
13.04.2017 16.07.00.770 In main thread stop

Т.е. нифига не работает.

Тестовый проект прилагаю.

test094 ForceQueue test.7z

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 ответов на этот вопрос

  • 0

Добавил запрос https://quality.embarcadero.com/browse/RSP-17841 , хотя их никто не читает...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
2 часа назад, Евгений Корепов сказал:

Т.е. нифига не работает.

А может не работает потому что неправильно написано? На мой взгляд MyLog не потокобезопасная процедура, а вы к ней обращаетесь из разных потоков. Из своего опыта я бы даже для Windows так делать не стал бы, один раз прокатит другой нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 минуту назад, GASCHE сказал:

А может не работает потому что неправильно написано? На мой взгляд MyLog не потокобезопасная процедура, а вы к ней обращаетесь из разных потоков. Из своего опыта я бы даже для Windows так делать не стал бы, один раз прокатит другой нет.

Все с ней хорошо, ведь там есть

TThread.Synchronize(Nil,
    procedure
    begin
      Memo.Lines.Add(LMessage);
    end);

К тому же это упрощенный вариант, в рабочем вместо Memo использовалась отсылка данных на сервер логов. Результат тот же.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
6 минут назад, Евгений Корепов сказал:

Все с ней хорошо

Думаю нет, вы не знаете какой поток к ней обратиться в тот или иной момент времени. В Windows у вас отрабатывает сначала основной поток потом ForceQueue в андроид ForceQueue вклинивается в основной поток.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 13.04.2017 в 19:06, GASCHE сказал:

Думаю нет, вы не знаете какой поток к ней обратиться в тот или иной момент времени. В Windows у вас отрабатывает сначала основной поток потом ForceQueue в андроид ForceQueue вклинивается в основной поток.

Напишите свой, "правильный" код если хотите доказать что TThread.ForceQueue работает в андроиде и я ошибаюсь. К чему этот бесполезный флуд?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

А что это вообще за метод TThread.ForceQueue? Где вы его взяли, его же нет в TThread.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
11 минуту назад, Maximus сказал:

А что это вообще за метод TThread.ForceQueue? Где вы его взяли, его же нет в TThread.

В токио

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


  • Похожий контент

    • От zekelive
      Добрый день, товарищи. Если кто сталкивался, подскажите) в потоке создаются картинкив виде плиток и прочие компоненты и падают на scrollbox.  Но в runtime пролистывание лагает, да в целом вся программа подлагивает. Можно ли как то реализовать подгрузка в фоне без ущерба? Или может ещё какой способ есть?
    • От Вольдемар
      Пользуюсь в своем Android приложении этим компонентом, вроде всё работает. Но хотелось бы асинхронности. Помогите пожалуйста с примером, как сделать асинхронность и получать результат после Post. Спасибо
    • От Aptyp
      На моём Samsung Note 5 вокруг букв проглядываются линии. Причём пробовал 3 различных разрешения экрана, ничего не меняется. У друга на Xiaomi Redmi 4x такого не наблюдается.
      Что это может быть?
       


    • От om.pranayama
      Здравствуйте форумчане и профессионалы разработчики.
      Компилирую проект через C++Builder 10.2  под Android
      Появилась следующая проблема при использовании компонента TBitmapListAnimation
      Если приложение свернуть, а затем развернуть - то появляются жуткие глитчи в ввиде чёрных фонов вокруг компонентов, типа TImage, TButton.
      В Windows такая проблема - не наблюдается.
      Попытки вызвать Repaint или даже Invalidate для всей формы - положительного результата не дают.
      Пожалуйста, помогите решить эту проблему.
      //--------------------------------------------------------------------------------------------------------------------------------------------
      ТЕМУ МОЖНО УДАЛЯТЬ
      Причина не в TBitmapListAnimation а в TAniIndicator, который работал совместно с TBitmapListAnimation.
      Приношу извинения за беспокойство. Проблема была в TAniIndicator. Буду разбираться почему он так себя безобразно ведёт.
      Тему можно удалять.
    • От Aptyp
      В приложении:
          procedure TForm7.Button1Click(Sender: TObject);     var AIntent: JIntent;         AServiceName: string;     begin       AIntent := TJIntent.Create;       AServiceName := 'com.embarcadero.services.Service';       AIntent.setClassName( TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString( AServiceName ) );       AIntent.putExtra( TAndroidHelper.StringToJString( 'Code' ), 0 );       AIntent.putExtra( TAndroidHelper.StringToJString( 'Data' ), TAndroidHelper.StringToJString( 'DataString' ) );       TAndroidHelper.Activity.startService( AIntent );     end;
      В сервисе:
          procedure TDM.AndroidIntentServiceCreate(Sender: TObject);     begin       Toast( 'Create' );     end;          procedure TDM.AndroidIntentServiceHandleIntent(const Sender: TObject;       const AnIntent: JIntent);     begin       Toast( 'HandleIntent' );     end; Сообщение 'Create' показывается, а 'HandleIntent' нет. OnCreate срабатывает, но onHandleIntent не вызывается что бы я не делал. Может я что-то не так делаю?
    • От Roman V
      Всем привет. Учусь работать с ini-файлами на Android. И сразу же возникла проблема, которую никак не могу решить. Хотел написать подобие приложение-тест с хранением данных в ini файле. В итоге все отлично работает на windows,а под Андроид при запуске висит только значок firemonkey секунд 10 и приложение вырубается так и не запустившись. В чем может быть проблема? Использую отладку по USB. 
      TIniFile *Ini = new TIniFile(System::Ioutils::TPath::GetDocumentsPath() + PathDelim + "options.ini"); Юзаю эти библиотеки 
      #include <System.IOUtils.hpp> #include <System.IniFiles.hpp>  
    • От gonzales
      Доброго времени суток!
      Решаю следующую задачу, в приложении динамически формируются разные объекты, наследники от одного класса. При формировании объектов заполняется динамический массив этих элементов. Далее я хочу в отдельном потоке для каждого из элементов массива получить его состояние, то есть делаю запрос к серверу. Все это повешено на таймер, каждую секунду должен отрабатываться запрос. Все более менее работает в Windows, а на Андроиде со временем приложение валится. Вот код таймера, для читаемости я удалил куски с различными вариантами E. RootElements - это массив TEssense от которого есть наследники. Функции GetBoardCurrentValue, GetBoardMaxValue - по сути запросы к серверу. 
      Подскажите, правильно ли я оформляю работу с потоками для работы на Андроиде?
      procedure TForm1.MasterTimerTimer(Sender: TObject); begin TTask.Run( procedure var l, d, a: byte; i,j:integer; E: TEssence; p: Pointer; VirtualNode: IXMLNode; VirtualElementNode: IXMLNode; id: byte; begin l := Length(Form1.RoomElements); for j := 0 to l - 1 do begin E := Form1.RoomElements[j]; // Реле if E is TRele then begin d := (E as TRele).Device_ID; a := (E as TRele).Device_Adress; if Form1.GetBoardCurrentValue(d, a) = true then begin TThread.Synchronize(nil, procedure begin (E as TRele).ReleSwitch.IsChecked := Form1.device[d].Board[a].CurrentValue.ToBoolean; end); end; // (E as TRele).ReleOnTimer(E) end // Диммер else if E is TDimmer then begin d := (E as TDimmer).Device_ID; a := (E as TDimmer).Device_Adress; if Form1.GetBoardMaxValue(d, a) = true then begin TThread.Synchronize(nil, procedure begin if (Form1.device[d].Board[a].Type_ID = TType.Светодиод) or (Form1.device[d].Board[a].Type_ID = TType.Диммер220) then begin (E as TDimmer).DimmerValue.Text := (Form1.device[d].Board[a].MaxValue).ToString; end; end); end; // (E as TDimmer).DimmerOnTimer(E) end // Таймер else if E is TSTimer then begin id := (E as TSTimer).STimerIndex; Form1.FillHTTPRequest(0, 0, HTTP_GET_TIMER_INFO, id); if Form1.AnswerIsComming = HTTP_GET_TIMER_INFO then begin TThread.Synchronize(nil, procedure begin if Form1.HTTPAnswer.Data1 = 0 then (E as TSTimer).Interval.Text := 'OFF' else (E as TSTimer).Interval.Text := 'ON' end); end; // (E as TSTimer).STimerOnTimer(E); end; end; end); end;   
    • От andahay
      Доброго времени суток. Есть android приложение, в нем есть диалоговое окно, которое предлагает перейти в google play и скачать другое приложение (pro версию), с 2 кнопками (да/нет). Как реализовать этот переход в Google play, чтобы в нем сразу было загружено нужное приложение. Использую Delphi XE7
    • От zekelive
      Добрый день, друзья. Начал заниматься вопросом описанным в шапке и столкнулся со множеством непонятных для меня проблем. Как примерно должно выглядеть на Рис. ниже. Знаю, что сам список барабан выполнен в TlistBox. Есть хорошая ссылка на блог Ярослава тут. Пошерстил файлы в FMX, и не нашел ключа для своего дела. Может кто занимался этим? Я изначально брал TScrollBox, кидал на него Tlayout и в него TLabel. Но думаю, видимо не то совсем.

    • От zekelive
      Добрый день. Кто знает, подскажите, можно ли средствами firemonkey менять иконку приложения в рантайм либо после закрытия и повторного открытия приложения? На win вроде бы можно, статьи на форуме находил, а для Андроида найти не удалось.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу