У меня очень странная проблема. У меня есть AsyncTask
, который блокирует поток пользовательского интерфейса при повороте телефона.
Во-первых, позвольте мне заявить, что мне комфортно, когда мои Activity
уничтожаются и воссоздаются при вращении. Я сохраняю AsyncTask
в onRetainNonConfigurationInstance()
, отсоединяю от него Activity в onDestroy()
и присоединяюсь к нему в onCreate()
, используя getLastNonConfigurationInstance()
.
Все в порядке, пока AsyncTask
не выполняет тяжелой работы. Например, для отладки моей проблемы, у меня есть это, и он работает точно так, как ожидалось, без блокировки пользовательского интерфейса:
@Override
protected Boolean doInBackground(Void... params) {
boolean success = false;
final DbAdapter dbAdapter = dbService.getAdapter();
try {
// pretend to do some complicated work
Thread.sleep(20000);
success = true;
} catch (Exception e) {
e.printStackTrace();
}
return success;
}
Однако, если я изменю его, чтобы выполнить некоторую фактическую работу в фоновом режиме, я получу очень большую задержку между вызовом onPause()
для запуска вращения и вызовом onResume()
позже в новой ориентации. Эта задержка составляет десятки секунд, в течение которых пользовательский интерфейс находится в несогласованном состоянии (старый макет обрезан в новой ориентации), и кажется, что вращение блокируется на AsyncTask
. Единственное изменение - две строки внутри блока try:
@Override
protected Boolean doInBackground(Void... params) {
boolean success = false;
final DbAdapter dbAdapter = dbService.getAdapter();
try {
// actually do some complicated work
XmlParser parser = new XmlParser(context, dbAdapter);
success = parser.parse(source);
} catch (Exception e) {
e.printStackTrace();
}
return success;
}
context
- это глобальный контекст приложения, передаваемый конструктору AsyncTask
, поэтому я не думаю, что случайно сохранил ссылку на исходящий Activity
.
Что еще может быть не так?