0

On my previous post, I have asked about getting data from Http Get Request with a body in C#. Now I am facing another error, Android.Util.AndroidRuntimeException: 'Only the original thread that created a view hierarchy can touch its views.' Does anyone know how to resolve this issue?

Code

  var client = new HttpClient();

    var request = new HttpRequestMessage
    {
        Method = HttpMethod.Get,
        RequestUri = new Uri("my url"),
        Content = new StringContent("my json body content", Encoding.UTF8, "application/json"),
    };

    var response = await client.SendAsync(request).ConfigureAwait(false);
    response.EnsureSuccessStatusCode();
    var responsebody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
    string text = responsebody.ToString();
    string[] str = text.Split(new[] { ',', ':' }, StringSplitOptions.RemoveEmptyEntries);
    string result = str[10];
    labelTxt.Text = result;
Charis
  • 111
  • 3
  • 11
  • Try explaining which line you get the error. And what exactly you are trying to do. Also look here it seems possible duplicate of https://stackoverflow.com/questions/5161951/android-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-vi – curiousBoy Apr 09 '20 at 03:58
  • I got the error at `labelTxt.Text = result`. I am trying to pass in one of the value from the responsebody and get it to display in `labelTxt.Text`. – Charis Apr 09 '20 at 04:04
  • It's fairly common practice that you can only modify UI elements from the UI thread so it looks like you may need to invoke a thread – curiousBoy Apr 09 '20 at 04:14

3 Answers3

0

Try something like below (assuming this whole thing is a function called as "SomeFunction")

private void SomeFunction() {
 Device.BeginInvokeOnMainThread(() => {
  var client = new HttpClient();

  var request = new HttpRequestMessage {
   Method = HttpMethod.Get,
    RequestUri = new Uri("my url"),
    Content = new StringContent("my json body content", Encoding.UTF8, "application/json"),
  };

  var response = await client.SendAsync(request).ConfigureAwait(false);
  response.EnsureSuccessStatusCode();
  var responsebody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
  string text = responsebody.ToString();
  string[] str = text.Split(new [] {
   ',',
   ':'
  }, StringSplitOptions.RemoveEmptyEntries);
  string result = str[10];
  labelTxt.Text = result;
 });
}
curiousBoy
  • 6,334
  • 5
  • 48
  • 56
  • Hi, they prompt me to add async inside so I used `Device.BeginInvokeOnMainThread(async () =>` instead but it still does not work.. – Charis Apr 09 '20 at 05:44
0

Hi Please Try this Code.

public async static Task<T> GetResultAsync<T>(string Url)
{
    try
    {
        if (CrossConnectivity.Current.IsConnected)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(BaseUrl);
                client.DefaultRequestHeaders.Clear();
                client.SetBearerToken(Helpers.Settings.ServiceToken);
                client.DefaultRequestHeaders.Add("Language", Helpers.Settings.AppLanuageSetting);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpResponseMessage response = await client.GetAsync($"{Url}").ConfigureAwait(false);
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<T>(result,new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.None });
                }
                else
                {
                    return default(T);
                }
            }
        }
        else
        {
            Acr.UserDialogs.UserDialogs.Instance.Toast("Please check your internet connection");
            return default(T);
        }
    }
    catch (Exception Ex)
    {
        Logging.ErrorLog(Ex, "GetResultAsync");
        return default(T);
    }
}

and use this method

var results = await APIService.GetResultAsync>($"{ApiEndpoints}/{"Paramters1"}/{pageNo}");

Chetan Rawat
  • 578
  • 3
  • 17
0

As curiousBoy said above, you can only modify UI elements from the UI thread(Main Thread).

so you could try to put labelTxt.Text = result; inside Device.BeginInvokeOnMainThread method.

var client = new HttpClient();

var request = new HttpRequestMessage
{
    Method = HttpMethod.Get,
    RequestUri = new Uri("my url"),
    Content = new StringContent("my json body content", Encoding.UTF8, "application/json"),
};

var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responsebody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
string text = responsebody.ToString();
string[] str = text.Split(new[] { ',', ':' }, StringSplitOptions.RemoveEmptyEntries);
string result = str[10];
Device.BeginInvokeOnMainThread(() => {labelTxt.Text = result;});
Leo Zhu
  • 15,726
  • 1
  • 7
  • 23