I have an activity which has an async method in it. This async method is long running. After the async method returns, the UI needs to be updated and some of the controls reference the activity. At the moment, everything works correctly if you do not have a configuration change (like screen rotation) while the async task is running. However, if a configuration change happens while it is running, then the exception Activity is destroyed is thrown and the UI is not updated. From what reading I have done, this seems to be because the async method captures context and then tries to update the old context which is of course destroyed after the configuration change.
My question is: What are the best ways to solve this problem or at worst case scenario work around it?
I personally think you have only three options
To disable it permanently set ConfigurationChanges
[Activity(Label = "...", ConfigurationChanges = Android.Content.PM.ConfigChanges.KeyboardHidden | Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
To disable it temporary while task working you should disable rotation handling,
disable
this.RequestedOrientation = Android.Content.PM.ScreenOrientation.Nosensor;
enable
this.RequestedOrientation = Android.Content.PM.ScreenOrientation.Sensor;
If you are using fragment you can prevent fragment destroy with RetainInstance = true. That might work, but i never tested it.
You can cancel task with CancelationToken and restart it in OnRestoreInstanceState()
Here is example how to cancel task
{
CancellationTokenSource cts;
...
// If a download process is already underway, cancel it.
if (cts != null)
{
cts.Cancel();
}
// Now set cts to cancel the current process if the button is chosen again.
CancellationTokenSource newCTS = new CancellationTokenSource();
cts = newCTS;
try
{
//Send cts.Token to carry the message if there is a cancellation request.
await AccessTheWebAsync(cts.Token);
}
// Catch cancellations separately.
catch (OperationCanceledException)
{
ResultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
ResultsTextBox.Text += "\r\nDownloads failed.\r\n";
}
// When the process is complete, signal that another process can proceed.
if (cts == newCTS)
cts = null;
}
And in the task
async Task AccessTheWebAsync(CancellationToken ct)
{
...
// Retrieve the website contents from the HttpResponseMessage.
byte[] urlContents = await response.Content.ReadAsByteArrayAsync();
// Check for cancellations before displaying information about the
// latest site.
ct.ThrowIfCancellationRequested();
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With