Error: Only the original thread that created a view hierarchy can touch its views in Xamarin

10,075

Solution 1

You're calling GetServicesForUserCompleted method from SalonServicesClient on worker thread. Invoke it on the UI thread instead.

Solution 2

The linked article in the accepted answer talks about InvokeOnMainThread which is an IOS thing. No idea why it was accepted as an answer for Android as the question is tagged.

For Android you use Activity.RunOnUiThread. Relevant documentation is here: http://developer.xamarin.com/guides/android/advanced_topics/writing_responsive_applications/

Because you are rigging this up from somewhere that inherits from Activity you can just wrap the relevant code so this:

BookingAdapter expListAdapter = new BookingAdapter (this, listDataHeader,  listDataChild);
try{
    explistView.SetAdapter (expListAdapter);
    explistView.SetGroupIndicator (null);
}
catch(Exception e) {
    Toast.MakeText (this,e+"",ToastLength.Long).Show();   
}

becomes:

RunOnUiThread(() =>
{
    BookingAdapter expListAdapter = new BookingAdapter (this, listDataHeader,  listDataChild);
    try{
        explistView.SetAdapter (expListAdapter);
        explistView.SetGroupIndicator (null);
    }
    catch(Exception e) {
        Toast.MakeText (this,e+"",ToastLength.Long).Show();   
    }
});

That's really all there is to it.

Solution 3

Here is a cross platform solution in xamarin for this issue;

 Device.BeginInvokeOnMainThread(() =>
 {
   //Your code here
 });
Share:
10,075
suraj shukla
Author by

suraj shukla

freelancer

Updated on June 10, 2022

Comments

  • suraj shukla
    suraj shukla about 2 years

    I am getting an error error: Only the original thread that created a view hierarchy can touch its views

    in line

    BookingAdapter expListAdapter = new BookingAdapter (this, listDataHeader,  listDataChild);
    try{
    explistView.SetAdapter (expListAdapter);
    explistView.SetGroupIndicator (null);
    }
    catch(Exception e) {
    Toast.MakeText (this,e+"",ToastLength.Long).Show();
    }
    

    and here is my piece of code

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using System.ServiceModel.Web;
    using SalonServices;
    using System.ServiceModel;
    
    namespace PariSalon
    {
    [Activity (Label = "BookingRequest")]           
    public class BookingRequest : Activity
    {
        public List<GetServices> listDataHeader;
        public List<GetServices> services;
        Dictionary<GetServices, List<String>> listDataChild;
        ExpandableListView explistView;
        public static readonly EndpointAddress EndPoint = new EndpointAddress("http://xxx.xxx.Xx.xx/SalonService/SalonServices.svc");
        //public static readonly EndpointAddress EndPoint = new EndpointAddress("http://xxxx");
        private SalonServicesClient serviceClient;
    
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
    
            SetContentView(Resource.Layout.Booking_request);
            InitializeSalonServiceClient();
            Button submit = FindViewById<Button> (Resource.Id.button2);
    
    
            //string userid = "1";
            //serviceClient.GetServicesForUserAsync (userid);
            string userid = "1";
            serviceClient.GetServicesForUserAsync (userid);
            //serviceClient.GetServicesForUserAsync (userid);
    
            submit.Click += delegate {
                Intent intent = new Intent(this, typeof(Booking_Request_sent));
                StartActivity(intent);
            };
    
    
            // Create your application here
            /*          
    
            explistView.SetOnGroupClickListener( new OnGroupClickListener());
    
    //Catch click event attempt 2
            explistView.GroupClick += (object pobjSender,   ExpandableListView.GroupClickEventArgs pArgs) =>
            {
                int len = expListAdapter.GroupCount;
                for(int i=0;i<len;i++)
                {
    
                    if(i!=groupPosition)
                    {
                        explistView.CollapseGroup(i);
                    }
                    if(i==groupPosition){
                        if(explistView.IsGroupExpanded(groupPosition)){
                            explistView.CollapseGroup(groupPosition);
                        }
                        else {
                            explistView.ExpandGroup(groupPosition);
                        }
    
    
                    }
                }
            };*/
        }
        private void InitializeSalonServiceClient()
        {
            BasicHttpBinding binding = CreateBasicHttp();
            serviceClient = new SalonServicesClient(binding, EndPoint);
            //serviceClient.GetServicesForUserCompleted += GetServicesForUserCompleted;
            //serviceClient.GetProductDetailsCompleted += GetProductDetailsCompleted;
            serviceClient.GetServicesForUserCompleted += GetServicesForUserCompleted;
    
        }
    
    
        private void GetServicesForUserCompleted(object sender, GetServicesForUserCompletedEventArgs getServiceDataCompletedEventArgs)
        {
            string msg = null;
    
            if (getServiceDataCompletedEventArgs.Error != null)
            {
                msg = getServiceDataCompletedEventArgs.Error.Message;
            }
            else if (getServiceDataCompletedEventArgs.Cancelled)
            {
                msg = "Request was cancelled.";
            }
            else
            {
                services = new List<GetServices>(getServiceDataCompletedEventArgs.Result);
                prepareListData ();
                explistView = FindViewById<ExpandableListView> (Resource.Id.expandableselectservicetype);
                BookingAdapter expListAdapter = new BookingAdapter (this, listDataHeader, listDataChild);
                try{
                    explistView.SetAdapter (expListAdapter);
                    explistView.SetGroupIndicator (null);
                }
                catch(Exception e) {
                    Toast.MakeText (this,e+"",ToastLength.Long).Show();
                }
    
    
            }
    
        }
    
        private static BasicHttpBinding CreateBasicHttp()
        {
            BasicHttpBinding binding = new BasicHttpBinding
            {
                Name = "basicHttpBinding",
                MaxBufferSize = 2147483647,
                MaxReceivedMessageSize = 2147483647
            };
            TimeSpan timeout = new TimeSpan(0, 0, 50);
            binding.SendTimeout = timeout;
            binding.OpenTimeout = timeout;
            binding.ReceiveTimeout = timeout;
            return binding;
        }
    
    
        private void prepareListData() {
            listDataHeader = new List<GetServices>();
            listDataChild = new Dictionary<GetServices, List<String>>();
            listDataHeader.Clear ();
            if (services != null) {
                foreach (GetServices pd in services) {
                    listDataHeader.Add (pd);
                }
                // Adding child data
                //listDataHeader.Add("Top 250/n");
                //listDataHeader.Add("Now Showing");
                //listDataHeader.Add("Coming Soon..");      
    
                List<String> childLabel = new List<String> ();
                childLabel.Add ("Date :");
                childLabel.Add ("Time :");
                childLabel.Add ("User :");
                childLabel.Add ("Second User:");
                childLabel.Add ("Status :");
                childLabel.Add ("Cancel ");
    
                listDataChild.Add (listDataHeader.ElementAt (0), childLabel); // Header, Child data
                listDataChild.Add (listDataHeader.ElementAt (1), childLabel);
                listDataChild.Add (listDataHeader.ElementAt (2), childLabel);
            }
        }
    
    
    }
    }
    

    I have another adapter class but I think the error is only in this class. How can I solve this problem. Can any one please help me to solve this problem.