Recent

Author Topic: Application.ProcessMessages command, what is the alternative on android?  (Read 2454 times)

loaded

  • Hero Member
  • *****
  • Posts: 825
Hello to everyone,
I used the Application.ProcessMessages command in my windows application to keep the application breathing. I'm looking for an alternative method for the Android application.
Thank you in advance for your help.

Example Code
Code: Pascal  [Select][+][-]
  1. procedure TAndroidModule1.jDrawingView1Draw(Sender: TObject; countXY: integer;
  2.   X: array of single; Y: array of single; flingGesture: TFlingGesture;
  3.   pinchZoomScaleState: TPinchZoomScaleState; zoomScale: single);
  4. begin
  5.    randomize;
  6.    jDrawingView1.BackgroundColor:=colbrBlack;
  7.    for i:=0 to 5000 do // ~100000 do
  8.    begin
  9.    jDrawingView1.PaintColor:=TARGBColorBridge(Random(144));
  10.    jDrawingView1.DrawLine(0,0,i,jDrawingView1.Height);
  11.    //Application.ProcessMessages;
  12.    end;
  13. end;
  14.  
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1314
    • Lebeau Software
Re: Application.ProcessMessages command, what is the alternative on android?
« Reply #1 on: February 14, 2019, 07:15:32 pm »
I used the Application.ProcessMessages command in my windows application to keep the application breathing.

Don't do that.  It is always a sign of bad UI/code design.

I'm looking for an alternative method for the Android application.

Redesign your approach, for all platforms, even Windows.

First off, you should not call Randomize() more than once per process.  Call it at program startup.

Second, and most importantly, don't block the UI thread for lengthy operations.  ESPECIALLY important on mobile platforms, but even for desktop platforms, too.  UI painting is done frequently and should be fast.  If your painting is so slow that the user notices it, and the OS thinks the app is unresponsive because of it, then move the actual drawing to a worker thread instead, and have it draw onto an in-memory bitmap, and then notify the UI thread whenever a new bitmap is ready for use so it can trigger a repaint.  Every time the UI needs to be painted, let the UI thread paint by simply drawing the latest bitmap onto the UI, and keep that bitmap around for subsequent paints until a new bitmap is ready.

For example (may need tweaking to suit your needs, but you should get the idea):

Code: Pascal  [Select][+][-]
  1. type
  2.   TDrawingThread = class(TThread)
  3.   private
  4.     FBitmap: TBitmap;
  5.     FOnNewBitmap: TNotifyEvent;
  6.     procedure NewBitmapReady;
  7.   protected
  8.     procedure Execute; override;    
  9.   public
  10.     constructor Create(Width, Height: Integer); reintroduce;
  11.     destructor Destroy; override;
  12.     property Bitmap: TBitmap read FBitmap;
  13.     property OnNewBitmap: TNotifyEvent read FOnNewBitmap write FOnNewBitmap;
  14.   end;
  15.  
  16. constructor TDrawingThread.Create(Width, Height: Integer);
  17. begin
  18.   inherited Create(True);
  19.   FBitmap := TBitmap.Create;
  20.   FBitmap.Width := Width;
  21.   FBitmap.Height := Height;
  22. end;
  23.  
  24. destructor TDrawingThread.Destroy;
  25. begin
  26.   FBitmap.Free;
  27.   inherited;
  28. end;
  29.  
  30. procedure TDrawingThread.Execute; override;    
  31. begin
  32.   while not Terminated do
  33.   begin
  34.     FBitmap.Canvas.Lock;
  35.     try
  36.       FBitmap..Canvas.Brush.Color := clBlack;
  37.       FBitmap..Canvas.FillRect(Rect(0, 0, FBitmap.Width, FBitmap.Height));
  38.       for i := 0 to FBitmap.Width-1 do
  39.       begin
  40.         FBitmap.Canvas.Pen.Color := TColor(Random(144));
  41.         FBitmap.Canvas.MoveTo(0, 0);
  42.         FBitmap.Canvas.DrawLine(i, FBitmap.Height);
  43.       end;
  44.     finally
  45.       FBitmap.Canvas.Unlock;
  46.     end;
  47.     if Assigned(FOnNewBitmap) then
  48.       Synchronize(NewBitmapReady);
  49.   end;
  50. end;
  51.  
  52. procedure TDrawingThread.NewBitmapReady;
  53. begin
  54.   if Assigned(FOnNewBitmap) then
  55.     FOnNewBitmap(Self);
  56. end;
  57.  
  58. var
  59.   DrawingThread: TThread;
  60.   CurrentBitmap: TBitmap;
  61.  
  62. procedure TAndroidModule1.ModuleCreate(Owner: TComponent);
  63. begin
  64.   Randomize;
  65.   CurrentBitmap := TBitmap.Create;
  66.   DrawingThread := TDrawingThread.Create(5000, jDrawingView1.Height);
  67.   DrawingThread.OnNewBitmap := NewBitmapReady;
  68.   DrawingThread.Resume;
  69. end;
  70.  
  71. procedure TAndroidModule1.NewBitmapReady(Sender: TObject);
  72. begin
  73.   CurrentBitmap.Assign(DrawingThread.Bitmap);
  74.   jDrawingView1.Invalidate;
  75. end;
  76.  
  77. procedure TAndroidModule1.jDrawingView1Draw(Sender: TObject; countXY: integer;
  78.   X: array of single; Y: array of single; flingGesture: TFlingGesture;
  79.   pinchZoomScaleState: TPinchZoomScaleState; zoomScale: single);
  80. begin
  81.   // draw CurrentBitmap onto jDrawingView1 as needed...
  82. end;
  83.  
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Application.ProcessMessages command, what is the alternative on android?
« Reply #2 on: February 14, 2019, 07:42:07 pm »
Code: Pascal  [Select][+][-]
  1.    for i:=0 to 5000 do // ~100000 do
  2.    begin
  3.  

If you have high amount of items needed to draw on the screen, it is usually good to use a buffer.

Not sure about Android. On PC, drawing on the screen directly is slow. So we draw all the items on a buffer and copy the buffer to the screen in one single pass. This trick can reduce flickering and improve performance.

You can learn more about using buffer here (PC version):
https://forum.lazarus.freepascal.org/index.php/topic,38136.msg263143.html#msg263143

loaded

  • Hero Member
  • *****
  • Posts: 825
Re: Application.ProcessMessages command, what is the alternative on android?
« Reply #3 on: February 14, 2019, 08:02:07 pm »
Remy Lebeau and Handoko
Thank you for taking your precious time and writing your answer. I understand that I have to work more.
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

 

TinyPortal © 2005-2018