1

I'm coding for Android app with this function:

protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.conversation_list_activity);
        listViewConversationList = FindViewById<ListView>(Resource.Id.listViewConversationPreview);

        string url = ConstantManager.HOST;
        HttpClient oHttpClient = new HttpClient();


        var oTaskGetAsync = oHttpClient.GetAsync(new Uri(url));
        oTaskGetAsync.ContinueWith((oHttpResponseMessage) =>
        {
            var result = oHttpResponseMessage.Result.Content.ReadAsStringAsync().Result;
            listConversationPreview = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ConversationPreview>>(result);
            ConversationAdapter adapter = new ConversationAdapter(this, listConversationPreview);
            RunOnUiThread(() => listViewConversationList.Adapter = adapter);
            listViewConversationList.ItemClick += listViewConversationList_ItemClick;
        });

    }

I run it successfully but after I import some Nuget Packae for Android Support Design, now it throw a message like this.

I/Choreographer( 1962): Skipped 524 frames! The application may be doing too much work on its main thread.

Could you please tell me what I've done wrong?

Logan Du
  • 11
  • 5
  • http://stackoverflow.com/questions/14678593/the-application-may-be-doing-too-much-work-on-its-main-thread – Stephen Mar 22 '17 at 21:19
  • I wrote a blog on this that might help explain these concepts: https://blog.xamarin.com/tips-for-creating-a-smooth-and-fluid-android-ui/ – Jon Douglas Mar 22 '17 at 21:22

2 Answers2

0

Why don't you wrap the whole async call in it's own task? I would split this up in services though, but for the simplicity of it, this is what I would do:

protected override async void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    SetContentView(Resource.Layout.conversation_list_activity);
    listViewConversationList = FindViewById<ListView>(Resource.Id.listViewConversationPreview);
    await Task.Run(async() => {
        string url = ConstantManager.HOST;
        HttpClient oHttpClient = new HttpClient();
        string resultString = oHttpClient.GetAsStringAsync(new Uri(url));
        listConversationPreview = 
            Newtonsoft.Json.JsonConvert.DeserializeObject<List<ConversationPreview>>(resultString);
        ConversationAdapter adapter = new ConversationAdapter(this, listConversationPreview);
        RunOnUiThread(() => listViewConversationList.Adapter = adapter);
        listViewConversationList.ItemClick += listViewConversationList_ItemClick;
    }
}

Some sidenotes: When running async stuff like this in a lifecycle method (oncreate, etc) please keep in mind that the other lifecycle methods will still be processed e.g. OnResume might be executed before the OnCreate has finished - this can lead to some very strange issues that are hard to debug.

In this example you might need the WebAPI NUget package

Erik J.
  • 799
  • 6
  • 19
0

You can perform an async operation in an Android Activity by using Handler and Action, so they will not use the UI Thread.

Example:

protected override void OnResume()
{
    base.OnResume();
    Handler handler = new Handler();
    Action action = async delegate { await UpdateListView(); };
    handler.Post(action);
}

private async Task UpdateListView()
{
    //Get data from internet with async methods here and update the ListView
}
Alexandre
  • 565
  • 3
  • 9