Как узнать, что AsyncTask был запущен? - PullRequest
1 голос
/ 30 октября 2011

В одном из моих занятий у меня есть до шести разных AsyncTasks, которые могут выполняться на разных событиях.Все AsyncTasks обрабатывают изменения ориентации изящно (по крайней мере, я на это надеюсь).В onRetainNonConfigurationInstance () я возвращаю объект AsyncTask текущего запущенного AsyncTask.Позже, во время onCreate (), мне нужно выяснить, какой объект AsyncTask возвращается из getLastNonConfigurationInstance ().

Я использую контекст Activity во всех методах onPostExecute (), чтобы получить новое действие (если есть новоеодин).Я нашел эту концепцию здесь, в StackOverflow, и немного ее изменил, потому что мне не нравится эта парадигма «Работа с мусором при изменении ориентации».Надеюсь, что эта концепция верна.

В приведенном ниже коде вы найдете две разные AsyncTasks.Во время onRetainNonConfigurationInstance () я верну текущий запущенный AsyncTask.Моя проблема в onCreate ().Как узнать, какой объект возвращается?Что AsyncTask выполнял, когда сталкивалось изменение ориентации?

Обе AsyncTask отличаются во многих областях (не показаны здесь), поэтому я не использовал собственный расширенный базовый объект AsyncTask.

Большое спасибо зааванс.

public class MyActivity extends ListActivity {
    // First AsyncTask
    private class MyLoadAsyncTask extends AsyncTask<Void, Void, Cursor> {

        private MyActivity       context;
        private MyProgressDialog dialog;

        public MyLoadAsyncTask(MyActivity context) {
            super();

            this.context = context;
        }

        @Override
        protected Cursor doInBackground(Void... voids) {
            return MyApplication.getSqliteOpenHelper().fetchSoomething();
        }

        @Override
        protected void onPostExecute(Cursor cursor) {
            if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            }

            if (cursor != null) {
                context.startManagingCursor(cursor);
                context.adapter = new InternetradiosAdapter(context,
                                                            R.layout.row,
                                                            cursor,
                                                            new String[] { "text1",
                                                                           "text2" },
                                                            new int[] { R.id.row_text1,
                                                                        R.id.row_text2 } );
                if (context.adapter != null) {
                    context.setListAdapter(context.adapter);
                }
            }

            context.loadTask = null;
        }

        @Override
        protected void onPreExecute () {
            dialog = MyProgressDialog.show(context, null, null, true, false);
        }
    }

    private class MyDeleteAsyncTask extends AsyncTask<Void, Void, Boolean> {
        // Second AsyncTask
        private MyActivity       context;
        private MyProgressDialog dialog;
        private long             id;

        public MyDeleteAsyncTask(MyActivity context, long id) {
            super();

            this.context = context;
            this.id = id;
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            return MyApplication.getSqliteOpenHelper().deleteSomething(id);
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            }

            if (result) {
                context.doRefresh();
            }

            context.deleteTask = null;
        }

        @Override
        protected void onPreExecute () {
            dialog = MyProgressDialog.show(context, null, null, true, false);
        }
    }

    private MyDeleteAsyncTask deleteTask;
    private MyLoadAsyncTask   loadTask;

    @Override
    public void onCreate(Bundle bundle) {
        // ...
        // What Task is returned by getLastNonConfigurationInstance()?
        // ...
        // xxxTask = (MyXxxAsyncTask) getLastNonConfigurationInstance();
        // ...
        if (deleteTask != null) {
            deleteTask.context = this;
            deleteTask.dialog = MyProgressDialog.show(this, null, null, true, false);
        } else if (loadTask != null) {
            loadTask.context = this;
            loadTask.dialog = MyProgressDialog.show(this, null, null, true, false);
        } else {
            loadTask = new MyLoadAsyncTask(this);
            loadTask.execute();
        }
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        if (deleteTask != null) {
            if (deleteTask.dialog != null) {
                deleteTask.dialog.dismiss();
                deleteTask.dialog = null;
                return deleteTask;
            }
        } else if (loadTask != null) {
            if (loadTask.dialog != null) {
                loadTask.dialog.dismiss();
                loadTask.dialog = null;
                return loadTask;
            }

        return null;
    }
}

Ответы [ 2 ]

1 голос
/ 30 октября 2011

В вашем onCreate () добавьте:

    Object savedInstance = getLastNonConfigurationInstance();
    if(savedInstance instanceof MyDeleteAsyncTask){
        //it's a MyDeleteAsyncTask
    }else if(savedInstance instanceof MyLoadAsyncTask){
        //it's a MyLoadAsyncTask
    }
1 голос
/ 30 октября 2011

Я обнаружил, что лучший способ справиться с действиями, в которых есть несколько запущенных AsyncTasks, - это на самом деле вернуть объект, содержащий все запущенные, и автоматически повторно инициализировать все их контексты в onCreate(). Э.Г.

private class AsyncTaskList() {
  List<ActivityTask> tasks; //interface all of your AsyncTasks implement
  public void addTask() { /* add to list*/ }
  public void completeTask { /* remove from list */ }
  public void attachContext(Activity activity) {
    for ( ActivityTask task : tasks) {
      //You can also check the type here and do specific initialization for each AsyncTask
      task.attachContext(activity);
    }
  }
}

public void onCreate(Bundle bundle) {
  AsyncTaskList taskList = (AsyncTaskList) getLastNonConfigurationInstance();
  if (taskList != null) {
    taskList.attachContext(this);
  }
  ...
}

Теперь вам просто нужно добавлять и удалять задачи, когда они запускаются / заканчиваются.

...