手柄方向变化与运行的AsyncTask [英] Handle orientation change with running AsyncTask

查看:97
本文介绍了手柄方向变化与运行的AsyncTask的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用情况:

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

问题:

如果用户旋转设备,同时下载活动被破坏。在执行结束的AsyncTask的试图更新被破坏的活动结果查看未连接到窗口管理器

错误的解决方案:

我可以掩盖问题,一个安卓configChanges =定位| keyboardHidden |屏幕尺寸,但这个布局是不会被更新为横向

就是我要问:

是否有可能改变方向,改变传递给上下文的参考的的AsyncTask

这<一href="http://stackoverflow.com/questions/2224676/android-view-not-attached-to-window-manager#6240320">answer建议检查对话框不为空,但它不是我要找的。

<一个href="http://stackoverflow.com/questions/1111980/how-to-handle-screen-orientation-change-when-progress-dialog-and-background-thre#4481297">Here他建议使用WeakReference的(<一href="http://stackoverflow.com/questions/4220625/android-context-leaks-in-asynctask#4220746">here一个很好的片段就如何使用它),但我不明白,如果是我在寻找什么。

要更加明确,这是我在做什么,在onPostExecute:

  @覆盖
保护无效onPostExecute(自动结果){
    progress.dismiss();
    新DownloaderCaptcha(上下文).execute();
    ((EditText上)context.findViewById(R.id.editTextCaptcha))的setText()。
    context.findViewById(R.id.progrBar).setVisibility(View.VISIBLE);
    context.findViewById(R.id.captcha).setVisibility(View.INVISIBLE);

    如果(结果!= NULL){
        Storage.storeHistory(上下文,result.getTarga()的getValue());

        意图I =新的意图(背景下,MenuActivity.class);
        i.putExtra(结果,结果);
        context.startActivity(ⅰ);
    } 其他 {
        ErrorDialog.show(背景下,误差);
    }
}
 

解决方案

下面是我的建议:

  • 你的不可以使用机器人:configChanges 来解决这个问题。

  • 你的不可以使用活动#onRetainNonConfigurationInstance()来解决这一问题是(因为这种做法是去precated)。

  • 相反,使用保留的工人片段。我最近已经<一个href="http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html">posted文章 描述了如何使用保留的片段 s到处理配置更改。它解决了保留的的AsyncTask 跨越旋转变化很好的问题。基本上,您需要在您的的AsyncTask 片段,呼叫 setRetainInstance(真)片段,并报告的AsyncTask 的进步/结果回到它的活动通过保留片段

Use case:

The user start the app that will load a captcha. The user fill the captcha and try to download some information.

Problem:

If the user rotate the device while downloading the Activity is destroyed. At the end of the execution the AsyncTask is trying to update the destroyed Activity and the result is a "View not attached to window manager".

"Wrong" solution:

I can mask the problem with a android:configChanges="orientation|keyboardHidden|screenSize" but with this the layout is not going to be updated to landscape.

What I'm asking:

Is it possible to change the orientation and change the "reference" of the Context passed to the AsyncTask?

This answer suggest to check if the dialog is not null, but it's not what I'm looking for.

Here he suggests to use a WeakReference (here a nice snippet on how to use it) but I didn't understand if it's what I'm looking for.

To be more explicit this is what I'm doing in the 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);
    }
}

解决方案

Here are my tips:

  • Do not use android:configChanges to address this issue.

  • Do not use Activity#onRetainNonConfigurationInstance() to address it either (as this approach is deprecated).

  • Instead, use a retained worker Fragment. I've recently posted an article describing how to handle configuration changes using retained Fragments. It solves the problem of retaining an AsyncTask across a rotation change nicely. You basically need to host your AsyncTask inside a Fragment, call setRetainInstance(true) on the Fragment, and report the AsyncTask's progress/results back to it's Activity through the retained Fragment.

这篇关于手柄方向变化与运行的AsyncTask的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆