Хорошо, я думаю, что у меня есть это сейчас.
1
Ключом к первому пункту была эта ссылка:
http://code.google.com/p/android/issues/detail?id=2373
Это ошибка. В ссылке есть некоторый код, который полностью решил проблему с созданием новых экземпляров корневых операций, вместо того, чтобы просто перезапустить последнее активное действие (до нажатия кнопки home).
Я разместил код в верхней части метода onCreate, чуть ниже вызова super.onCreate:
if (!isTaskRoot()) {
final Intent intent = getIntent();
final String intentAction = intent.getAction();
if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) &&
intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
finish(); return;
}
}
Обратите внимание, что я добавил оператор return после финиша, чтобы остальная часть метода onCreate не выполнялась в случае обнаружения ошибки.
2. & 3.
Ключом ко второму и третьему пунктам были эти две ссылки:
http://answers.oreilly.com/topic/2692-android-programming-understanding-the-activity-life-cycle/
Как сделать Активность, не охватывающую весь экран
Оказывается, что «видимость» действительно буквально! Поэтому, когда в документации говорится, что «другое действие стоит перед действием», действие, стоящее за перемещенным действием, все еще частично видно. Это означает, что менеджер активности Android должен проверить, является ли активная операция полноэкранным действием или нет: если это так, onStop()
вызывается для предыдущего действия. Если нет, то вместо предыдущей операции вызывается onPaused()
.
Это тривиально объясняет, почему диспетчер USB-накопителя вызвал onStop()
.
Это также означает, что когда устройство переходит в спящий режим, Диспетчер активности считает его не полноэкранным, хотя технически основное действие полностью скрыто за ним.
(см. Вторую ссылку о том, как выполнять не полноэкранные операции)
Интересно, что раскрывающееся окно (с уведомлениями) не вызывает onPause()
(и при этом оно не вызывает onStop()
), даже если бы оно имело смысл как не полноэкранное действие. Это должно быть какое-то исключение, которое я буду расследовать самостоятельно.
Это также означает, что цикл onStop()-onRestart()
, вероятно, более распространен, чем цикл onPause()-onResume()
(хотя оба должны учитываться), поскольку действия, вероятно, чаще всего являются полноэкранными (лично я думал, что документация указала обратное: что onPause-onResume было более распространенным, но, возможно, это только я).
Кроме того, это должно означать, что, когда основное действие запускает новое полноэкранное действие для результата, основное действие будет сначала остановлено, а затем перезапущено после выполнения операции извлечения результата.
Таким образом, единственный вопрос сейчас заключается в том, как наилучшим образом справиться с приостановленной активностью (то есть, она покрыта не полноэкранным действием), которая освобождается (хотя этот случай будет редким). Какие проблемы могут быть?
Но это выходит за рамки этого вопроса.