Android Question Only the original thread that created a view hierarchy can touch its views.

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Hello to Everybody here
I have a small problem. "Small" because I can circumvent it, in this case, but it is not so small. As a matter of fact, first of all, the App, run in debug mode, doesn't display any problem and this puts the problem out of my knowledge. Therefore I would like to know the reason of the crash summarized in the post title. The log, reported hereunder, indicates where the problem arises. I have put two messages to identify the specific view doing the problem: Step_1 and STep_2. The crash appears after Step_1, which also shows that the label is initialized.. The App has a rather complex layout and cannot be reproduced here. The significant code is also reported here;

B4X:
Private Sub AbilitaShowCartesiane(come As Boolean)    ' come is True in this case
    Log("Step 1" & lblMostraCartesiane)
    
    lblMostraCartesiane.Visible=come
    lblMostraCartesiane.Enabled=come

    Log("Step 2")

    If come=True Then 
        lblMostraCartesiane.BringToFront 
        ShowingCart=1
    Else 
        lblMostraCartesiane.SendToBack
        ShowingCart=0
    End If
End Sub

As you see in the following log, the crash is between step_1 and step_2, therefore involves "lblMostraCartesiane" label. The label is initialized, as shown in the log (because it is loaded with a previous LoadLayout, where the label itself is declared (as initially not visible and not enabled). I tried to change its parent, because originally this label had a Panel as parent, and I unsuccessfully changed the parent to Activity. Myy empirical solution is to move the activation of the lblMostraCartesiane in another position of the App working flow, calling the AbilitaShowCartesiane with an explicit choice of the User, putting a button.Doing so, no crash. Maybe it is useful to know that the Panel which is the father of the label, is connected with an OpenGL object. The involved sub, anyway, is called after that this panel and the relative OpenGL stuff is initialized. (BTW I point out that also if the Label has Activity as Parent, nothing changes, and that the Debugger doesn't stop; the problem arises only in Release Mode). Thanks for any hint.

*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
(RuntimeException) java.lang.RuntimeException: Cannot parse: null as boolean ' didn't see where this happens, must investigate further (could be the reason?)
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
** Activity (main) Resume **
Step 1(TextView): Enabled=false, Visible=false, Left=16, Top=16, Width=794, Height=81, Tag=, Text=
b4xmainpage_abilitashowcartesiane (java line: 665)
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:9910)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1976)
at android.view.View.requestLayout(View.java:26466)
at android.view.View.requestLayout(View.java:26466)
at android.view.View.requestLayout(View.java:26466)
at android.view.View.requestLayout(View.java:26466)
at android.view.View.requestLayout(View.java:26466)
at android.view.View.requestLayout(View.java:26466)
at android.view.View.setFlags(View.java:16916)
at android.view.View.setVisibility(View.java:12329)
at anywheresoftware.b4a.objects.ViewWrapper.setVisible(ViewWrapper.java:271)
at Geoide.GOrto.b4xmainpage._abilitashowcartesiane(b4xmainpage.java:665)
at Geoide.GOrto.b4xmainpage._glsv_draw(b4xmainpage.java:4502)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.agraham.opengl2.GLWrapper2$GLSurfaceViewWrapper2$myRenderer.onDrawFrame(GLWrapper2.java:1734)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1581)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1280)
 

agraham

Expert
Licensed User
Longtime User
Maybe it is useful to know that the Panel which is the father of the label, is connected with an OpenGL object
I haven't seen your actual code so I can't see exactly what is going on but this is probably it. OpenGL renders on a different thread to the main thread so you can't touch any views created by OpenGL on the main thread and OpenGL can't touch any views created on the main thread.
 
Last edited:
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
I haven't seen your actual code so I can't see exactly what is going on but this is probably it. OpenGL renders on a different thread to the main thread so you can't touch any views created by OpenGL on the main thread and OpenGL can't touch any views created on the main thread.
Of course you cannot know the details. Now I solved the problem using CallSubDelayed2(Me,"AbilitaShowCartesiane",true), instead of calling the sub directly. The position of the call, anyway, is the same (i.e. CallSubDelayed2(...) instead of AbilitaShowCartesiane...). Probably you may understand the reason or the need of this fact.... Thanks a lot.
 
Upvote 0

AnandGupta

Expert
Licensed User
Longtime User
Call sub delayed, works as the name suggests and was created for that.
Where direct call sub, do not work.
 
Upvote 0
Top