Can I use TThread in android app in the same way like for windows app? lazarus / 43-Android ---------------------------------------------------------------------- Atak_Snajpera · 2021-11-25 17:29 I have added cthreads to lpr file then I try creating and running thread the same how I do on windows. Simple example: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TWorkerThread = class(TThread)  private    { Private declarations }  x:integer;    procedure UpdateValue;  protected    procedure Execute; override;  end;     Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.ButtonClick(Sender: TObject);begin       WorkerThread:=TWorkerThread.Create(true);     WorkerThread.FreeOnTerminate:=false;     WorkerThread.Priority:=tpNormal;     WorkerThread.Start; end;       Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TWorkerThread.Execute;begin   x:=0;       repeat         Inc(x);       Synchronize(UpdateValue);         sleep(1000);   until Terminated=true; end;   Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TWorkerThread.UpdateValue;begin   form1.jTextView.text:=IntToStr(x);  end; When I press button in android emulator nothing happens! ---------------------------------------------------------------------- engkin · 2021-11-26 04:32 TThread works on Android. Synchronize needs CheckSynchronize to be called inside the main loop of the app. This is by default on Windows for GUI applications. Not on terminal or Android apps. You can add it there. Test TThread without Synchronize. ---------------------------------------------------------------------- Atak_Snajpera · 2021-11-26 19:06 Where should I put CheckSynchronize exactly? ---------------------------------------------------------------------- MarkMLl · 2021-11-26 19:20 Seconded. @engkin, could we have a concise example please? MarkMLl ---------------------------------------------------------------------- engkin · 2021-11-27 00:27 I'll provide an example as soon as get a chance. ---------------------------------------------------------------------- engkin · 2021-11-27 08:45 While other possibilities are there, I'll assume LAMW is being used here since the original post mentioned jTextView. If you followed my first reply, you'll see the thread is working but can not call Synchronize. To prove that Synchronize works, simply add a jTimer to your main form and have it call CheckSynchronize(). If you are satisfied with this timer, good for you. A call to Synchronize uses WakeMainThread. Which makes finding a way to call CheckSynchronize on the main thread simple. Android provides RunOnUiThread. Unfortunately the implementation in LAMW is not correct. It uses PJNIEnv of the main thread instead of the calling thread. A thread var can be filled by each thread. Along these lines: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i threadvar  env:PJNIEnv;//<--- has to be a threadvar procedure TWorkerThread.Execute;begin  gVM^.AttachCurrentThread(gVM,@env,nil);//<--- needed for every thread  WakeMainThread:=LetsWakeMainThread;//<--- needed once  x:=0;  repeat  inc(x);    Synchronize(UpdateValue);    Sleep(1000);  until Terminated;  gVM^.DetachCurrentThread(gVM);//<--- when you are done with the thread (Free/Destroy)end; LetsWakeMainThread is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TWorkerThread.LetsWakeMainThread(Sender:TObject);begin  //MainForm.RunOnUiThread(Integer(Self));//<--- Wrong env variable, not for this thread  TAndroidModule1(MainForm).RunOnUiThread_corrected(env,0);end; RunOnUiThread_corrected  is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TAndroidModule1.RunOnUiThread_corrected(correct_env:PJNIEnv;_tag: integer);begin  //in designing component state: set value here...  if Initialized then     jni_proc_i(correct_env, jSelf, 'RunOnUiThread', _tag);end; And the most important part is to add CheckSynchronize() to the OnRunOnUiThread event of the main form: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure T AndroidModule1.AndroidModule1RunOnUiThread(Sender:TObject;tag:integer) ;begin  CheckSynchronize();end; Full code of the thread: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit uThreadTest; {$mode delphi} interface uses  Classes, SysUtils,  AndroidWidget,And_jni; type   { TWorkerThread }   TWorkerThread=class(TThread)  private    procedure UpdateValue;  protected    procedure Execute; override;  public    MainForm:jForm;  x:integer;    OnUpdate:Procedure of object;     procedure LetsWakeMainThread(Sender: TObject);  end; implementationuses  unit1; { TWorkerThread } procedure TWorkerThread.UpdateValue;begin  if Assigned(OnUpdate) then    OnUpdate;end; threadvar  env:PJNIEnv;//<--- has to be a threadvar procedure TWorkerThread.Execute;begin  gVM^.AttachCurrentThread(gVM,@env,nil);//<--- needed for every thread  WakeMainThread:=LetsWakeMainThread;//<--- needed once  x:=0;  repeat  inc(x);    Synchronize(UpdateValue);    Sleep(1000);  until Terminated;  gVM^.DetachCurrentThread(gVM);//<--- when you are done with the thread (Free/Destroy)end; procedure TWorkerThread.LetsWakeMainThread(Sender:TObject);begin  //MainForm.RunOnUiThread(Integer(Self));//<--- Wrong env variable, not for this thread  TAndroidModule1(MainForm).RunOnUiThread_corrected(env,0);end; end. Main form relevant code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TAndroidModule1.LetsUpdate;begin  jTextView1.Text:=WorkerThread.x.ToString;end; procedure TAndroidModule1.RunOnUiThread_corrected(correct_env:PJNIEnv;_tag: integer);begin  if Initialized then     jni_proc_i(correct_env, jSelf, 'RunOnUiThread', _tag);end; procedure TAndroidModule1.StartBtnClick(Sender:TObject);begin  if WorkerThread=nil then  begin    WorkerThread:=TWorkerThread.Create(True);    WorkerThread.MainForm:=Self;    WorkerThread.OnUpdate:=LetsUpdate;    WorkerThread.Start;  end;end; procedure TAndroidModule1.StopBtnClick(Sender:TObject);begin  WorkerThread.Terminate;end; ---------------------------------------------------------------------- MarkMLl · 2021-11-27 09:04 Thanks very much for that, it gives me a good incentive to look at LAMW and possibly to investigate threads on Termux. MarkMLl ---------------------------------------------------------------------- jmpessoa · 2021-11-27 15:14 @engkin Nice! Can you, please, put your LAMW project in some "open drive"  (or here, if possible) So we can add it to LAMW "demos"! Thank you! ---------------------------------------------------------------------- engkin · 2021-11-27 20:36 Quote from: jmpessoa on November 27, 2021, 04:14:33 pmCan you, please, put your LAMW project in some "open drive"  (or here, if possible) Done! ---------------------------------------------------------------------- jmpessoa · 2021-11-28 05:55 Done! Thank you! ---------------------------------------------------------------------- Atak_Snajpera · 2022-09-01 23:06 "Unfortunately the implementation in LAMW is not correct. It uses PJNIEnv of the main thread instead of the calling thread. " Has this been already fixed in latest version of lamw?