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

Андрей Рулин

Пользователи
  • Постов

    75
  • Зарегистрирован

  • Посещение

  • Победитель дней

    1

Сообщения, опубликованные Андрей Рулин

  1. В 10.01.2022 в 18:20, krapotkin сказал:

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

    Там у меня выше как раз 2 разных потока. Основной код в одно, обновление в другом. 

    Или вы хотите , чтобы я вычисления вынес в дополнительный поток. К сожалению так не получится, т.к. у меня в реальной задаче идёт чтение из файла вместе с вычислениями. А на адройде чтение из файла идёт только в основном потоке. Я этот вопрос уже задавал в другой ветке, пока ни у кого не получилось чтение файла в побочном потоке. 

     

    В 10.01.2022 в 18:50, GASCHE сказал:

    По таймеру запускаете поток, в процедуре

    procedure TThreadRenew.Execute;

    производите расчет, когда значение внутри измениться на 1 синхронизируйтесь с основным потоком и меняете 

    Label1.Text

    и даже "если вычисления идут час", то через час будет вам счастье 🙂

     

    См. выше. К сожалению в побочном потоке не читаются файлы на Android. Только в основном.  Я попробую выложить тестовую задачу, где будет это видно. 

  2. В 29.12.2021 в 17:01, OnePeople сказал:

    ну так у вас 10 раз inc(pc)

    Правильно. И после каждого inc(pc) ожидается , что будет  ОТОБРАЖАТЬСЯ +1%

    В 29.12.2021 в 17:19, GASCHE сказал:

    for i := 0 to 9 do begin 

    уберите и будет вам счастье

    Ну извините, это в тестовом коде можно убрать, а не в реальных.  Данный код , это максимальное упращение кода в сотни строк, и в это упрощении ошибка всё ещё появляется. Cуть в том, чтобы  выполнять вычисления и параллельно отображаеть ход этих вычислений. Если убрать цикл, это значит просто последовательно вести СНАЧАЛА вычисления, а ПОТОМ отображение. А если вычисления идут час. И что , мы должны час оставлять пользователя с зависшей программой? Это не дело! 

     

    Наверное я очень плохо обясняю, попытаюсь то же сказать более формальный языком.

    УСЛОВИЯ ТЕСТИРОВАНИЯ.  Delphi 10.4 , системы Windows , Android приведённый тестовый код.

    ОЖИДАЕМЫЙ РЕЗУЛЬТАТ  для цикла for i := 0 to 9 do после КАЖДОГО изменения inc(pc);  должно отображаться изменение на 1%, например 49%...50%...51%

    ФАКТИЧЕСКИЙ РЕЗУЛЬТАТ (для Android)  для цикла for i := 0 to 9 do изменения отображается ПОСЛЕ ЗАВЕРШЕНИЯ ЦИКЛА. В виде 40%...50%...60% (для всех вариантов кода). 

    ФАКТИЧЕСКИЙ РЕЗУЛЬТАТ (для Windows)  cовпадает с ОЖИДАЕМЫМ РЕЗУЛЬТАТОМ для кода в посте от 29.12.2021 15:02

     

     

     

     

  3. Вот такой код работает в Windows. Но в андройде , увы и ах... По 10% прибавляет.

    unit Unit2;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
      FMX.Controls.Presentation, FMX.StdCtrls;
    
    type
      TForm2 = class(TForm)
        Timer1: TTimer;
        Label1: TLabel;
    
        procedure Timer1Timer(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
    
        { Public declarations }
      end;
    
    TThreadRenew = class(TThread)
      MainFlag : Boolean;
      constructor Create;
      Destructor Destroy;
      procedure Execute; override;
      procedure ChangeL2;
    end;
    
    var
      Form2: TForm2;
      ThreadRenew : TThreadRenew;
      pc: integer;
      Busy : Boolean = False;
    implementation
    
    {$R *.fmx}
    
    
    
    
    procedure TForm2.FormCreate(Sender: TObject);
    begin
       ThreadRenew := TThreadRenew.Create;
    end;
    
    procedure TForm2.Timer1Timer(Sender: TObject);
    var
    i,j,k:Integer;
    a:Double;
    begin
      if Busy then exit;
      Busy := True;
      if pc >=100 then
      begin
        Timer1.Enabled := false;
        ThreadRenew.MainFlag :=False;
      end
      else
       for i := 0 to 9 do
        begin
         for j := 0 to 5000 do
           for k := 0 to 10000 do
              begin
                a:=a+k/1000+k/500;
              end;
          inc(pc);
          Application.ProcessMessages;
        end;
      //inc(pc);
      Busy := False;
    end;
    
    
    
    
    
    constructor TThreadRenew.Create;
    begin
      inherited Create(False);  //Автозапуск потока
      MainFlag := True;
    end;
    
    destructor TThreadRenew.Destroy;
    begin
      inherited  Destroy;
    end;
    
    procedure TThreadRenew.ChangeL2;
    begin
       Form2.Label1.Text := format('%d%%', [pc]);
      // Form2.Invalidate;
    end;
    
    procedure TThreadRenew.Execute;
    begin
      while MainFlag do
        begin
          Synchronize(ChangeL2);
          //Synchronize(Form2.Invalidate);
          //Synchronize(Application.ProcessMessages);
          //if Stage>=4 then MainFlag := False
                      //else
          Sleep(100);
        end;
    
    end;
    
    
    
    
    end.

     

  4. Вот как у вас и должно быть, чтобы по 1%.  А у меня изменяется по 10%  .  А если вы j до 10 000 или 15 000 делаете , всё равно по 10% изменяется?  Может у вас процессор быстрый?  И я, если что компилировал в 10.4. 

  5. В 02.11.2021 в 12:36, krapotkin сказал:

    ProcessMessages оставим в VCL. Не будет тут так работать.

    Если вычисления в таймере то оно и так нормально должно работать. Значит, что-то умалчивается.

    Ну почему же, вот мы ваш код модифицируем и введём вычисления.

     

    procedure TForm2.Timer1Timer(Sender: TObject);
    var
    i,j,k:Integer;
    a:Double;
    begin
      if pc >=100 then
      begin
        Timer1.Enabled := false;
        exit;
      end;
       for i := 0 to 9 do
        begin
         for j := 0 to 5000 do
           for k := 0 to 10000 do
              begin
                a:=a+k/1000+k/500;
              end;
          inc(pc);
          Label1.Text := format('%d%%', [pc]);
        end;
      //inc(pc);
    end;

    Он даже в Windows будет обновляться по десяткам процентов , а надо , чтобы по единицам, причём даже  если j до 10000 и более поставить, когда он не успевает завершить вычисления за отведённое время. 

  6. В 11.08.2021 в 16:43, krapotkin сказал:

    Создайте поток, в нем через Synchronize() изменяйте компоненты, и все заработает

    Вот кстати по этому методу я написал следующий код 


     

    procedure TThreadRenew.ChangeL2;
    begin
       Form2.Label2.Text:=IntToStr(CalibPercentw)+'%';
    end;
    
    procedure TThreadRenew.Execute;
    begin
      while MainFlag do
        begin
          Synchronize(ChangeL2);
          //Synchronize(Form2.Invalidate);
          Sleep(1000);
        end;
    
    end;

    В Windows всё работает изменения идут ровно раз в секунду. В Андройде, увы...  Как только вычисления заканчивается, тогда да, обновляет. 

  7. Вот я по GetScreenScale нашёл интересную тему, тут разработчик подтверждает, что экран растягивает, если выставить разрешение меньше фактического. 

    https://fire-monkey.ru/topic/24-получаем-разрешение-экрана-устройства-логические-и-физические-размеры-экрана-в-firemonkey/

    Но если выставить больше, он не говорит, что происходит. 

    Судя по документации 

    https://docwiki.embarcadero.com/Libraries/Sydney/en/FMX.Platform.IFMXScreenService.GetScreenScale

    Коэффициент может быть только больше

    Цитата

    However, a screen with a significantly different pixel density may set this property to a higher value.

    И плюс непонятно какие могут быть значения. 

    В одном топике говорилось про 1, 1.5 ,2 . Тут фиксированный ряд или они могут быть любыми? 

  8. У меня до этого все приложения были для ориентации Landscape. Я ставил разрешение, например 800x450 . После этого приложение растягивалось на любом телефоне, и всё работало. 

    Теперь я сделал приложение с портретной ориентации и разрешением 720x1280 . И оно не помещается на экран - в телефоне отображается только часть экрана. 

    Почему в одном случае растягивается , а в другом нет, и что нужно сделать для исправления ситуации? 

  9. Версия Дельфи 10.4.

    Я создаю в assets папку img , и итоге при запуске приложения в лог у меня пишется

     /storage/emulated/0/Android/data/com.embarcadero.ИмяПриложения/files/img/имя_файла.jpg 

    То есть , что надо, то он и пытается читать.

    Но при этом в Android32 всё происходит успешно, а в Android64 программа зависает. Кто виноват и что делать? ?

     

    P.S. В версии Android32 работает так(второй вариант ниже не проверял). 

     WriteDebug('Image '+S+' will read');
                TempStream := TFileStream.Create(S,0);  //Может так всё же лучше
                //TempStream.LoadFromFile(S);
                Image2.MultiResBitmap.LoadItemFromStream(TempStream,1);
                TempStream.Free;

    В Android64 не работает ни так как выше , ни так:

    WriteDebug('Image '+S+' will read');
    Image2.Bitmap.LoadFromFile(S);

     

    В Windows 32 работают оба варианта. 

  10. Если с самого начала, при проектировании приложения задать произвольный шрифт, например 12 , то потом можно программно его изменить через TextSettings.Font.Size := xxx;

    Но если оставить шрифт Default , то  потом шрифт программно нельзя изменить.  Есть какие-то методы, чтобы можно было изменить размер шрифта в любом случае?

  11. Не реагируют компоненты Memo, Label.  HitTest установлено на True. 

    Если создать новый проект и перекопировать в него код со старого, но вручную пересоздать Label и Memo, то всё работает.

    В чём может быть ошибка? А то не хотелось бы по 10 раз сохранять проект, чтобы потом к старому откатываться, когда всё опять случайно поломается. 

  12. У меня есть приложение, которое , как и любое обычное можно открыть по нормальному , а можно опцией "во всплывающем окне". Вот видео где оно открывается и так и так

     

    https://drive.google.com/file/d/11A1MmpOO6jfX8AAfyMw0QyrhgP7z94oh/view?usp=sharing

    Хотелось, бы  запретить такой вариант открытия, чтобы можно было открыть только полноэкранно.

    Если так нельзя , то хотелось бы чтобы когда пользователь открывал во всплывающем окне, оно всё-таки переводило в полноэкранный режим.

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

     

  13. Попробовал ещё раз. Самсунг публикует, но и в этот раз на тестировании завернул приложение, правда в этот раз тут моя вина, как разработчика.  Huawei маринует, где-то 4 дня и больше, но потом публикует. 

    Вот пример , как он опубликовал мой проект - https://appgallery.huawei.com/#/app/C104694755

     

    В 27.08.2021 в 21:31, Delpher-X сказал:

    И да, все эти магазины приложений - они требуют от разработчика его паспортные данные? В том числе, Google Play? 

     

    Самсунг вроде не требует, но я год назад регистрировался может не помню уже . Huawei точно требует.  Ещё они требуют политику конфиденциальности. Но её можно генератором наклепать. 

    Amazon appstore  - скорее всего не требует. 

  14. Цитата

    скорость прорисовки - раза в три хуже чем на java, хотя странно, тут код нативный, и работает медленнее 

    Причём у меня программа есть , я её на с 10.0 на 10.4 перевёл, и скорость отрисовки почему-то упала.  Стали видны "артефакты". 

    Цитата

    новые версии андроида часто несовместимые со старыми версиями делфи. программа написанная на java пашет и не падает, на делфи просто перестала запускаться на 11 андроиде. 

    У них с файлами стал новый механизм.  По крайней мере у меня из-за этого программы на 10.0 перестали запускаться. 

  15. Я таки нашёл, что конкретно портиться. 

     

    Цитата

    При этом файл device_filter.xml   располагается в .\assets\internal 

    А изначально она была в res\xml  - вот это и портит 10.4 , на неправильную папку меняет. Если на правильную исправить, то размещает. 

  16. Вот по тому, народ старается ничего не выкладывать. Ибо всегда найдутся "вумные", которые дельного совета дать не могут, зато их будет "бомбить" от посторонних вещей. 

    Да, ведь хотел всё на Java перевести и лишний раз убеждаюсь, что была правильная мысль. На Дельфи к сожалению остаётся всё меньше, а в FMX и вовсе понимают Крапоткин и ещё полтора человека. А глюков гораздо больше, чем на Java.

    P.S. Я и новый проект с нуля создавал, потом старые файлы подключал, всё равно, увы и ах. 

     

  17. Осваиваю новую версию 10.4. . Там конечно же не без "чуч" 

    У меня в манифесте прописан device_filter ,который определяет устройства, на которые есть реакция на их подключение. 

    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                    android:resource="@xml/device_filter" />

     

    При этом файл device_filter.xml   располагается в .\assets\internal 

    У версии 10.0 всё нормально компилируется, и развёртывается.

    У версии 10.4. тоже всё компилируется но при развёртовании ошибка

     

    [PAClient Error] Error: E2312 D:\Мои программы\Delphi\Androind-USB\MagnMet _FMX-Beta_pob104\Android\Debug\Detector\AndroidManifest.xml:37: error: Error: No resource found that matches the given name (at 'resource' with value '@xml/device_filter').

    Более того, после того, как эта ошибка вылетает, я уже и на 10.0 ничего сделать не могут, вылетает та же ошибка. Чем-то напоминает глюку , когда дельфи не мог генерировать vrc , если ему подсунуть проект, сгенерированый старой версией. 

     

    Кто-то сталкивался? Как решал? 

     

     

  18. Amazon appstore  довольно демократичный магазин, публиковался в нём. Жалко, что пользователей у него, похоже немного.

    Магазин Samsung требует фактически Google аккаунта - если просто выложить, то заблокирует как ненадёжный источник. 

  19. Цитата

    тут читали про Suspend ?? логично же да?

    "undefined behavior within your application"  подозреваю всё же не о том, что одной платформе будет работать , а на другой "кроссплатформенная" FMX как обычно будет виснуть.

    Цитата

    создавать циклы, используя конструкцию TParallel.For;

    Нет , в данном случае плохо.  Т.к. данная система создаёт и убивать потоки, это очень много времени занимает. 

    Вот я создал даже пример https://drive.google.com/file/d/17qjew0kjq8mjnIFSjvHG3MYHW84GnksT/view?usp=sharing

    Блок по 1600 байт всё равно написанная на коленке версия через TThread по принципу крякнул-бахнул опережает TParallel.For .  И только на блоках 6400 байт и более начинается выгода.  А не всегда удаётся распараллелить на такие большие блоки.

    И вот , кстати я переписал , что файл читается в основном потококе и тогда заработало.

    Цитата

    procedure TThreadSignal.ReadBuf;
    begin

    if ThreadFile.BytesReady<=Counter then
        begin
          fCompleted  := True;
          if fi>0 then Suspend //Только старшему потоку разрешено читать   //Ждём пока буфер не будет прочитан.
          else ReadFileThread;

     

    Подозреваю ,  что в андройде BlockRead можно только из основного потока вызывать. 

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