В наши дни есть гораздо более четкий способ решения подобных проблем. Типичный подход:
1. Убедитесь, что ваши данные правильно отделены от пользовательского интерфейса:
Все, что является фоновым процессом, должно храниться в Fragment
(установите это значение с помощью Fragment.setRetainInstance()
. Это становится вашим «постоянным хранилищем данных», где хранятся все данные на основе, которые вы хотели бы сохранить. После события изменения ориентации этот Fragment
по-прежнему будет доступен в своем первоначальном состоянии через вызов FragmentManager.findFragmentByTag()
(когда вы создаете его, вы должны присвоить ему тег , а не ID , поскольку он не присоединен к View
) .
См. Обработка изменений во время выполнения , разработанную для получения информации о том, как сделать это правильно, и почему это лучший вариант.
2. Убедитесь, что вы правильно и безопасно взаимодействуете между фоновыми процессами и вашим пользовательским интерфейсом:
Вы должны отменить процесс связывания. В данный момент ваш фоновый процесс присоединяется к View
- вместо этого View
должен присоединиться к фоновому процессу. Это имеет больше смысла, верно? Действие View
зависит от фонового процесса, тогда как фоновый процесс не зависит от View
. Это означает изменение ссылки на стандартный интерфейс Listener
. Скажем, ваш процесс (независимо от того, какой это класс - будь то AsyncTask
, Runnable
или любой другой) определяет OnProcessFinishedListener
, когда процесс завершится, он должен вызвать этот слушатель, если он существует.
Этот ответ является хорошим кратким описанием того, как сделать пользовательских слушателей.
3. Свяжите свой пользовательский интерфейс с процессом обработки данных при каждом создании пользовательского интерфейса (включая изменения ориентации):
Теперь вам нужно беспокоиться о сопряжении фоновой задачи с текущей структурой View
. Если вы правильно обрабатываете изменения (не всегда рекомендуют хакеры configChanges
), то ваш Dialog
будет воссоздан системой. Это важно, это означает, что при изменении ориентации все ваши методы жизненного цикла Dialog
будут вызваны. Таким образом, в любом из этих методов (onCreateDialog
, как правило, хорошее место), вы можете сделать вызов, подобный следующему:
DataFragment f = getActivity().getFragmentManager().findFragmentByTag("BACKGROUND_TAG");
if (f != null) {
f.mBackgroundProcess.setOnProcessFinishedListener(new OnProcessFinishedListener() {
public void onProcessFinished() {
dismiss();
}
});
}
См. Жизненный цикл Fragment , чтобы узнать, где настройка слушателя лучше всего подходит для вашей индивидуальной реализации.
Это общий подход к обеспечению надежного и полного решения общей проблемы, задаваемой в этом вопросе. Вероятно, в этом ответе пропущено несколько незначительных частей в зависимости от вашего индивидуального сценария, но, как правило, это наиболее правильный подход для правильной обработки событий изменения ориентации.