如何在服务中使用AsyncTask时保存状态?

时间:2012-03-06 13:08:40

标签: android android-asynctask

我一直在使用AsyncTask,而我遇到的最大问题是应用程序崩溃了很多次并且渲染发生的次数太多了。例如,如果我在特定布局上设置数据并对其进行渲染,然后转动屏幕,则会再次使用另一个GET请求向服务器呈现整个布局以获取数据。不关心它,甚至认为twitter也有同样的问题。好像他们修好了。

因此,如何在服务中使用AsyncTask并且还具有我可以参考的实例状态,以检查屏幕何时转动或甚至应用程序崩溃。

1 个答案:

答案 0 :(得分:3)

我确实在活动中遇到了与asynctask类似的问题:活动在屏幕旋转时被销毁并重新创建,因此重新创建了asynctask。

解决这个问题:

  • 简单但不优雅:在您的活动清单中使用android:configChanges =“orientation”防止活动被破坏。

  • 有点复杂:创建一个存储当前活动控件的类,将其保存在onRetainNonConfigurationInstance中并在onCreate中恢复它。当asynctask开始时,它不是直接与活动交谈,而是与通过轮换持续存在的这个类进行对话。如果你愿意,我可以提供一些代码(它有点长)。

编辑:这是一些代码。

        package com.ybi;

        import android.app.Activity;
        import android.os.AsyncTask;
        import android.os.Bundle;
        import android.widget.TextView;

        public class EmptyShellActivity extends Activity {

            private ActivityControl activityControl;
            private EmptyShellTask emptyShellTask;

            private TextView textView;


            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                textView = (TextView)findViewById(R.id.textView1);
                restoreFromObject();
            }

            @Override
            public Object onRetainNonConfigurationInstance() {
                activityControl.textView = null;
                return activityControl;
            }

            private void restoreFromObject() {
                activityControl = (ActivityControl) getLastNonConfigurationInstance();
                if (activityControl == null) {
                    activityControl = new ActivityControl();
                    activityControl.textView = textView;
                    activityControl.textView.setText("Doing");
                    emptyShellTask = new EmptyShellTask();
                    emptyShellTask.execute((Void[])null);
                } else {
                    activityControl.textView = textView;
                    if (activityControl.isInProgress)
                        activityControl.textView.setText("Doing");
                    else
                        activityControl.textView.setText("Done");
                }
            }

            protected class ActivityControl {
                protected boolean isInProgress;
                protected TextView textView;
            }

            private class EmptyShellTask extends
            AsyncTask<Void, Void, Void> {

                @Override
                protected Void doInBackground(Void... params) {
                    activityControl.isInProgress = true;
                    try {
                            Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // say something
                    }
                    return null;
                }

                @Override
                protected void onPostExecute(Void result) {
                    super.onPostExecute(result);
                    activityControl.isInProgress = false;
                    activityControl.textView.setText("Done");
                }
            }
        }

我刚从班上的一个人那里删除了一些东西。我通常使用接口而不是在postExecute中编写代码。它有助于防止在任何地方都有代码片段(比如重复完成完成显示)。

如果你想进一步(如进度控制,取消任务,错误管理),我有一段有趣的代码。唯一的问题是它变得非常复杂。