处理屏幕旋转并运行AsyncTask

8

使用场景:

用户启动应用程序加载验证码。用户填写验证码并尝试下载一些信息。

问题:

如果用户在下载过程中旋转设备,则Activity会被销毁。在执行结束时,AsyncTask正在尝试更新已销毁的Activity,结果是"View not attached to window manager"

"错误"解决方案:

我可以使用android:configChanges="orientation|keyboardHidden|screenSize"掩盖问题,但是这样布局将不会更新为横向布局。

我的问题:

是否可以更改方向并更改传递给AsyncTask的上下文的“引用”?

这个答案建议检查对话框是否为空,但这不是我要找的。

这里他建议使用WeakReference(这里提供了一个很好的代码片段),但我不知道这是否是我要找的。

更明确地说,这是我在onPostExecute中所做的:

@Override
protected void onPostExecute(Auto result) {
    progress.dismiss();
    new DownloaderCaptcha(context).execute("");
    ((EditText)context.findViewById(R.id.editTextCaptcha)).setText("");
    context.findViewById(R.id.progrBar).setVisibility(View.VISIBLE);
    context.findViewById(R.id.captcha).setVisibility(View.INVISIBLE);

    if(result != null) {
        Storage.storeHistory(context, result.getTarga().getValue());

        Intent i = new Intent(context, MenuActivity.class);
        i.putExtra("result", result);
        context.startActivity(i);
    } else {
        ErrorDialog.show(context, error);
    }
}

这不是最好的答案,但你可以在asyncTask上保留一个引用并将其传递给你的landscape activity。然后,landscape activity将更新asynctask上下文... 但我不知道如果你的ascncTask在activity转换期间完成会发生什么(但是有简单的解决方案来解决此问题)。 - Xval
@matiash:没必要踩,因为如果你看回答发布的时间,那是在Alex发布这个之后!所以当时没有一个好的答案回答我的问题。显然你可以标记它为重复,但是贬低是意味着缺乏研究,我想这不是我的情况。只是我的个人意见。 - Enrichman
@Enrichman 我没有给它投反对票。我同意这是一个好问题,只是重复了。 - matiash
@matiash 没问题,我看到旗帜就知道是你了。 :) - Enrichman
2个回答

16
以下是我的提示:
  • 不要使用android:configChanges来解决这个问题。

  • 也不要使用Activity#onRetainNonConfigurationInstance()来解决它(因为这种方法已经过时了)。

  • 相反,使用一个保留的工作Fragment。我最近发布了一篇文章,介绍如何使用保留的Fragment处理配置更改。它很好地解决了在旋转更改中保留AsyncTask的问题。你只需要将AsyncTask放在一个Fragment中,调用setRetainInstance(true)方法,在保留的Fragment中报告AsyncTask的进度/结果给它的Activity


1
我在尝试实现这个时遇到了一些问题,但我想这是最好的解决方案。谢谢 :) - Enrichman
我非常喜欢这个答案。 :) - Alex

0
"错误"解决方案: 我可以通过android:configChanges="orientation|keyboardHidden|screenSize"来掩盖问题,但是这样布局不会更新到横屏。
实际上会更新。
android:configChanges列出了活动本身将处理的配置更改。当运行时发生配置更改时,默认情况下会关闭并重新启动活动,但声明具有此属性的配置将防止活动重新启动。相反,活动保持运行状态,并调用其onConfigurationChanged()方法。
请参见http://developer.android.com/guide/topics/manifest/activity-element.html#config 您可以为横向和纵向模式实现布局,或在配置更改时取消您的AsyncTask。

当然有了。它将改变方向,但使用的布局是为纵向模式定义的布局。 - Enrichman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接