locked
Exception: Only the original thread that created a view hierarchy can touch its views RRS feed

  • Question

  • User91562 posted

    The code below works on Windows Phone but when running on Android I am getting the following exception : android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

            public ButtonLoggerPage()
                    {
                        // Create the Button and attach Clicked handler.
                        Button button = new Button
                        {
                            Text = "Log the Click Time"
                        };
    
                        button.Clicked += OnButtonClicked;
                        opusClient.LoginCheckCompleted += OpenReadLogincheck;
    
                        this.Padding = new Thickness(5, Device.OnPlatform(20, 0, 0), 5, 0);
    
                        tbSyncItemLbl = new Label { };
    
                        // Assemble the page.
                        this.Content = new StackLayout
                        {
                            Children = { button,new ScrollView { VerticalOptions = LayoutOptions.FillAndExpand,
    
                            BackgroundColor = Color.Gray,
                            Content = loggerLayout}
                            }
                        };
                    }
    
            void OnButtonClicked(object sender, EventArgs args)
                {
    
                            loginCheck();
    
                }
    
         public void loginCheck()
                {
                    try
                    {
    
    
                        client.LoginCheckAsync(username, password);
                    }
                    catch (Exception e)
                    {
    
                        receiveErrors = 22;
                    }
                }
    
        void OpenReadLogincheck(Object sender, LoginCheckCompletedEventArgs e)
        {
    
    
                    if (e.Result != null)
                    {
                        LoginStatus = e.Result.Value;
                        if (e.Result == 1)
                        {
                            addMessage("Login Succeeded", Direction.Download);
    
                        }
    

    } }

            public enum Direction { Upload, Download, DownloadFailed, UploadFailed };
    
                 public void setSyncItem(string itemName, Direction dir)
                        {
                            tbSyncItemLbl.Text += itemName +" " + Environment.NewLine;
    
    
                            if (dir == Direction.Download)
                            {
                                this.tbSyncItemLbl.TextColor = Color.FromHex("B5DF26");
                            }
                            else if (dir == Direction.Upload)
                            {
                                this.tbSyncItemLbl.TextColor = Color.FromHex("527EA5");
                            }
                            else if (dir == Direction.DownloadFailed)
                            {
                               this.tbSyncItemLbl.TextColor = Color.FromHex("FF0000");
                            }
                            else if (dir == Direction.UploadFailed)
                            {
                               this.tbSyncItemLbl.TextColor = Color.FromHex("FF0000");
                            }
    
                            this.tbSyncItemLbl.YAlign = TextAlignment.Center;
    
                        }
    
             private void addMessage(string item, Direction dir)
                    {
                              setSyncItem(item, dir);
                            loggerLayout.Children.Add(tbSyncItemLbl);                   
                    }
    
            Label tbSyncItemLbl ;
    
    Tuesday, January 13, 2015 2:03 PM

All replies

  • User84987 posted

    It's fairly common practice that you can only modify UI elements from the UI thread. Also, XF is not a phone OS in itself but rather just a tool that makes it easier to develop cross-platform apps (a distinction that seems to be forgotten quite a bit on this forum).

    Internally the different phone OS' will handle threading, UI updates, etc... differently so you're likely to see things happening differently on different platforms.

    There's quite a bit missing to be able to help debug your issue but what I would suggest is seeing if you can get a callstack for the offending UI update and determine where in your code the issue arises and wrapping that in Device.BeginInvokeOnMainThread(Action) to make sure any UI updates are occurring on the correct thread.

    For instance, you might change addMessage to:

    private void addMessage(string item, Direction dir)
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            setSyncItem(item, dir);
            loggerLayout.Children.Add(tbSyncItemLbl);
        });
    }
    
    Tuesday, January 13, 2015 4:32 PM
  • User91562 posted

    Thanks Jon

    This is the all exception:

    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4925) at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:950) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.widget.ScrollView.requestLayout(ScrollView.java:1685) at android.view.View.requestLayout(View.java:15461) at android.widget.HorizontalScrollView.requestLayout(HorizontalScrollView.java:1687) at android.view.View.requestLayout(View.java:15461) at android.view.View.requestLayout(View.java:15461) at android.view.ViewGroup.addView(ViewGroup.java:3489) at android.view.ViewGroup.addView(ViewGroup.java:3436) at android.view.ViewGroup.addView(ViewGroup.java:3412) at dalvik.system.NativeStart.run(Native Method) } Android.Util.AndroidRuntimeException

    Tuesday, January 13, 2015 4:39 PM
  • User91562 posted

    Many thanks Jon. I have changed the addMessage and it is working.

    Tuesday, January 13, 2015 5:15 PM
  • User234063 posted

    @LuckyDay said: It's fairly common practice that you can only modify UI elements from the UI thread. Also, XF is not a phone OS in itself but rather just a tool that makes it easier to develop cross-platform apps (a distinction that seems to be forgotten quite a bit on this forum).

    Internally the different phone OS' will handle threading, UI updates, etc... differently so you're likely to see things happening differently on different platforms.

    There's quite a bit missing to be able to help debug your issue but what I would suggest is seeing if you can get a callstack for the offending UI update and determine where in your code the issue arises and wrapping that in Device.BeginInvokeOnMainThread(Action) to make sure any UI updates are occurring on the correct thread.

    For instance, you might change addMessage to:

    private void addMessage(string item, Direction dir)
    {
      Device.BeginInvokeOnMainThread(() =>
      {
          setSyncItem(item, dir);
          loggerLayout.Children.Add(tbSyncItemLbl);
      });
    }
    

    This worked like charm to me!! Thanks Tones!! :)

    Friday, January 6, 2017 8:13 PM
  • User335817 posted

    Thanks. It's help me.

    Tuesday, August 8, 2017 4:35 AM
  • User344289 posted

    Thanks. Can confirm this works just fine at least on Android.

    Monday, August 28, 2017 5:56 PM
  • User342288 posted

    Thanks for help! I love you

    Thursday, October 19, 2017 9:26 PM
  • User285957 posted

    @LuckyDay said: It's fairly common practice that you can only modify UI elements from the UI thread. Also, XF is not a phone OS in itself but rather just a tool that makes it easier to develop cross-platform apps (a distinction that seems to be forgotten quite a bit on this forum).

    Internally the different phone OS' will handle threading, UI updates, etc... differently so you're likely to see things happening differently on different platforms.

    There's quite a bit missing to be able to help debug your issue but what I would suggest is seeing if you can get a callstack for the offending UI update and determine where in your code the issue arises and wrapping that in Device.BeginInvokeOnMainThread(Action) to make sure any UI updates are occurring on the correct thread.

    For instance, you might change addMessage to:

    private void addMessage(string item, Direction dir)
    {
      Device.BeginInvokeOnMainThread(() =>
      {
          setSyncItem(item, dir);
          loggerLayout.Children.Add(tbSyncItemLbl);
      });
    }
    

    Thanks

    Working B)

    Thursday, March 1, 2018 10:54 AM
  • User366616 posted

    I was getting same error in my code, In my case I am using ProgressDialog to set Image on ImageView, below code helped me to resolve this, setting image on same thread resolved me this error.

    Additional from above answers, Hope this helps too!!

    if (bitmap != null) RunOnUiThread(() => navImage.SetImageBitmap(bitmap));

                        RunOnUiThread(() => navImage.Click += NavImage_Click);
    
    Saturday, May 19, 2018 1:42 AM
  • User378863 posted

    @LuckyDay said: It's fairly common practice that you can only modify UI elements from the UI thread. Also, XF is not a phone OS in itself but rather just a tool that makes it easier to develop cross-platform apps (a distinction that seems to be forgotten quite a bit on this forum).

    Internally the different phone OS' will handle threading, UI updates, etc... differently so you're likely to see things happening differently on different platforms.

    There's quite a bit missing to be able to help debug your issue but what I would suggest is seeing if you can get a callstack for the offending UI update and determine where in your code the issue arises and wrapping that in Device.BeginInvokeOnMainThread(Action) to make sure any UI updates are occurring on the correct thread.

    For instance, you might change addMessage to:

    private void addMessage(string item, Direction dir)
    {
      Device.BeginInvokeOnMainThread(() =>
      {
          setSyncItem(item, dir);
          loggerLayout.Children.Add(tbSyncItemLbl);
      });
    }
    

    Thks i looking for this. [in my Receving notification put it inside a label in the view and do other functions with xamarin c#code] :) :)

    Tuesday, January 15, 2019 8:05 PM
  • User382500 posted

    Friend Lucky Day

    Thanks for the hint! It helped me a lot!

    Device.BeginInvokeOnMainThread(() => { //PERFECT!! });

    Wednesday, February 13, 2019 12:31 PM
  • User383560 posted

    I'm getting error in the insertpagebefore var root = MasterDetail.Detail.Navigation.NavigationStack[0]; MasterDetail.Detail.Navigation.InsertPageBefore(page, root); Device.BeginInvokeOnMainThread(async () => { await MasterDetail.Detail.Navigation.PopToRootAsync(false); });

    I'm not sure what is going wrong now? It worked fine previously

    Monday, April 15, 2019 6:02 AM
  • User343509 posted

    @LuckyDay said: It's fairly common practice that you can only modify UI elements from the UI thread. Also, XF is not a phone OS in itself but rather just a tool that makes it easier to develop cross-platform apps (a distinction that seems to be forgotten quite a bit on this forum).

    Internally the different phone OS' will handle threading, UI updates, etc... differently so you're likely to see things happening differently on different platforms.

    There's quite a bit missing to be able to help debug your issue but what I would suggest is seeing if you can get a callstack for the offending UI update and determine where in your code the issue arises and wrapping that in Device.BeginInvokeOnMainThread(Action) to make sure any UI updates are occurring on the correct thread.

    For instance, you might change addMessage to:

    private void addMessage(string item, Direction dir)
    {
      Device.BeginInvokeOnMainThread(() =>
      {
          setSyncItem(item, dir);
          loggerLayout.Children.Add(tbSyncItemLbl);
      });
    }
    

    It's working for me

    Friday, May 24, 2019 7:05 AM
  • User387243 posted

    @LuckyDay said: It's fairly common practice that you can only modify UI elements from the UI thread. Also, XF is not a phone OS in itself but rather just a tool that makes it easier to develop cross-platform apps (a distinction that seems to be forgotten quite a bit on this forum).

    Internally the different phone OS' will handle threading, UI updates, etc... differently so you're likely to see things happening differently on different platforms.

    There's quite a bit missing to be able to help debug your issue but what I would suggest is seeing if you can get a callstack for the offending UI update and determine where in your code the issue arises and wrapping that in Device.BeginInvokeOnMainThread(Action) to make sure any UI updates are occurring on the correct thread.

    For instance, you might change addMessage to:

    private void addMessage(string item, Direction dir)
    {
      Device.BeginInvokeOnMainThread(() =>
      {
          setSyncItem(item, dir);
          loggerLayout.Children.Add(tbSyncItemLbl);
      });
    }
    

    Its Work, Thank you :smiley:

    Monday, July 15, 2019 5:54 PM
  • User29828 posted

    Thanks, I spent more time than I care to admit trying to debug what I thought was a binding issue, but no its because it was another thread. Thanks Device.BeginInvokeOnMainThread(() => { LoadingImage.IsVisible=false; }

    Tuesday, November 24, 2020 3:10 AM