Forum > Android

Can I use TThread in android app in the same way like for windows app?

<< < (2/2)

engkin:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TAndroidModule1.AndroidModule1RunOnUiThread(Sender:TObject;tag:integer);begin  CheckSynchronize();end;

Full code of the thread:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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:
Thanks very much for that, it gives me a good incentive to look at LAMW and possibly to investigate threads on Termux.

MarkMLl

jmpessoa:
@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:

--- Quote from: jmpessoa on November 27, 2021, 04:14:33 pm ---Can you, please, put your LAMW project in some "open drive"  (or here, if possible)

--- End quote ---

Done!

jmpessoa:

Done!

Thank you!

Navigation

[0] Message Index

[*] Previous page

Go to full version