我的活动中有一个异步方法。这种异步方法长期运行。异步方法返回后,需要更新UI,并且某些控件引用该活动。 目前,如果在异步任务运行时没有配置更改(如屏幕旋转),一切都能正常工作。但是,如果在运行时发生配置更改,则会抛出异常Activity被销毁并且UI不会更新。从我所做的阅读开始,这似乎是因为异步方法捕获了上下文,然后尝试更新旧的上下文,当然在配置更改后会被破坏。
我的问题是:解决这个问题的最佳方法是什么,或者在最坏的情况下解决这个问题?
答案 0 :(得分:2)
我个人认为你只有三个选择
永久禁用设置ConfigurationChanges
[Activity(Label = "...", ConfigurationChanges = Android.Content.PM.ConfigChanges.KeyboardHidden | Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
在任务正常工作时暂时禁用,您应禁用旋转处理
禁用
this.RequestedOrientation = Android.Content.PM.ScreenOrientation.Nosensor;
使
this.RequestedOrientation = Android.Content.PM.ScreenOrientation.Sensor;
如果您正在使用片段,则可以使用RetainInstance = true
防止片段破坏。这可能有用,但我从未测试过。
您可以使用CancelationToken
取消任务,然后在OnRestoreInstanceState()
重新启动
以下是取消任务的示例
{
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;
}
在任务中
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();
...
}
答案 1 :(得分:0)
你可以做很多事情,但请不要去禁用手机转动屏幕的能力 - 这只会忽略你的用户。
在高级别你必须做两件事:
您可以通过将任务移入应用程序类或(清理器)到setRetainInstance设置为true的无头片段来解决此问题。
这是阻止异步任务调用旧上下文的原因,可以通过异步任务上的简单java setter来完成。如果活动当前未连接,请不要忘记将结果缓存在任务中。
答案 2 :(得分:0)
最后我最终做的是将异步任务封装在另一个类中,该类持有对当前活动的引用,该类实现了接口,定义了一个处理异步响应并更新UI的方法。
活动保存了封装的异步任务的静态变量,如果它在配置更改期间运行,则封装的异步对活动的任务引用已更新为新活动。