为了账号安全,请及时绑定邮箱和手机立即绑定

Android碎片。在屏幕旋转或配置更改期间保留AsyncTask

Android碎片。在屏幕旋转或配置更改期间保留AsyncTask

富国沪深 2019-09-18 13:43:56
我正在使用智能手机/平板电脑应用程序,只使用一个APK,并根据屏幕大小根据需要加载资源,最佳设计选择似乎是通过ACL使用Fragments。这个应用程序一直工作正常,直到现在只是基于活动。这是一个模拟类,用于处理活动中的AsyncTasks和ProgressDialogs,以便在屏幕旋转或通信中发生配置更改时使它们工作。我不会改变清单以避免重新创建活动,有很多原因我不想这样做,但主要是因为官方文档说它不是推荐的,而且我已经管理了这么远,所以请不要推荐路线。public class Login extends Activity {    static ProgressDialog pd;    AsyncTask<String, Void, Boolean> asyncLoginThread;    @Override    public void onCreate(Bundle icicle) {        super.onCreate(icicle);        setContentView(R.layout.login);        //SETUP UI OBJECTS        restoreAsyncTask();    }    @Override    public Object onRetainNonConfigurationInstance() {        if (pd != null) pd.dismiss();        if (asyncLoginThread != null) return (asyncLoginThread);        return super.onRetainNonConfigurationInstance();    }    private void restoreAsyncTask();() {        pd = new ProgressDialog(Login.this);        if (getLastNonConfigurationInstance() != null) {            asyncLoginThread = (AsyncTask<String, Void, Boolean>) getLastNonConfigurationInstance();            if (asyncLoginThread != null) {                if (!(asyncLoginThread.getStatus()                        .equals(AsyncTask.Status.FINISHED))) {                    showProgressDialog();                }            }        }    }    public class LoginThread extends AsyncTask<String, Void, Boolean> {        @Override        protected Boolean doInBackground(String... args) {            try {                //Connect to WS, recieve a JSON/XML Response                //Place it somewhere I can use it.            } catch (Exception e) {                return true;            }            return true;        }这段代码工作正常,我有大约10,000个用户没有抱怨,所以将这个逻辑复制到新的基于片段的设计似乎合乎逻辑,但是,当然,它不起作用。我不能使用,onRetainNonConfigurationInstance()因为它必须从Activity而不是Fragment调用,同样如此getLastNonConfigurationInstance()。我在这里读过一些类似的问题而没有答案。据我所知,它可能需要一些解决方法才能将这些东西正确地组织成片段,据说,我希望保持相同的基本设计逻辑。在配置更改期间保留AsyncTask的正确方法是什么,如果它仍在运行,则显示progressDialog,同时考虑到AsyncTask是Fragment的内部类,而Fragment本身调用AsyncTask.execute ()?
查看完整描述

3 回答

?
四季花海

TA贡献1811条经验 获得超5个赞

碎片实际上可以使这更容易。只需使用Fragment.setRetainInstance(boolean)方法,即可在配置更改中保留您的片段实例。请注意,这是docs中Activity.onRetainnonConfigurationInstance()的推荐替代品。


如果由于某种原因你真的不想使用保留的片段,你可以采取其他方法。请注意,每个片段都有Fragment.getId()返回的唯一标识符。您还可以通过Fragment.getActivity()。isChangingConfigurations()查看是否正在拆除片段以进行配置更改。因此,在您决定停止AsyncTask(最有可能在onStop()或onDestroy()中)的情况下,您可以检查配置是否正在更改,如果是,则将其粘贴在片段标识符下的静态SparseArray中,然后在你的onCreate()或onStart()中查看你是否在稀疏数组中有一个AsyncTask。


查看完整回答
反对 回复 2019-09-18
?
慕容森

TA贡献1853条经验 获得超18个赞

我最近发布了一篇文章,描述了如何使用retain Fragments 处理配置更改。它解决了保持AsyncTask旋转变化很好的问题。


TL; DR是使用你的AsyncTask内部主机a Fragment,调用setRetainInstance(true)它Fragment,并通过保留AsyncTask来报告它的进度/结果Activity(或者它的目标Fragment,如果你选择使用@Timmmm描述的方法)Fragment。


查看完整回答
反对 回复 2019-09-18
  • 3 回答
  • 0 关注
  • 404 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信