Жизненный цикл активности Android: почему сначала не вызывается супер-метод?
Одно из требований базовой разработки под Android (согласно документации Google) заключается в том, что при переопределении методов жизненного цикла действия (onCreate, onResume, onPause и т. Д.) Сначала необходимо вызвать метод родителя:
@Override
protected void onResume()
{
super.onResume();
}
Почему Android API не использует шаблон невиртуального интерфейса для реализации этого поведения, а не полагается на то, что разработчики не забывают сделать это?:
Класс Activity Base Android может выглядеть примерно так (сырой пример):
public class Activity
{
public final void onResume()
{
// do important things here
virtualOnResume();
}
protected abstract void virtualOnResume();
}
Детский класс, написанный разработчиком Android:
public class MainActivity extends Activity
{
@Override
protected void virtualOnResume()
{
// do custom stuff here, without needing to call super.onResume()
}
}
Я не сталкивался со случаем, когда мне нужно написать какие-либо инструкции до вызова метода super. Есть ли время, когда мы НЕ должны вызывать супер метод или не вызывать его первым? Если это действительно всегда должно быть первым для какого-либо конкретного метода в жизненном цикле, то какова была причина решения о дизайне не использовать паттерн NVI для его применения?
ОБНОВЛЕНИЕ: разрабатывая для Android какое-то время, все на работе используют мой класс BaseActivity NVI, и у меня все еще не возникла причина НЕ использовать NVI для всех методов жизненного цикла, кроме метода onCreate. Похоже, что те, кто ответил / прокомментировал в защиту существующего дизайна API, на самом деле не имеют оправдания или, кажется, не понимают, что такое паттерн NVI, поэтому я предполагаю, что ничего хорошего причина в том, что это "просто так".
2 ответа
Вам не нужно вызывать супер метод в качестве первого утверждения вашего метода. Иногда вы можете захотеть сделать что-то до и после вызова супер-метода.
Смотрите FragmentActivity, например:
@Override
protected void onCreate(Bundle savedInstanceState) {
mFragments.attachActivity(this, mContainer, null);
// Old versions of the platform didn't do this!
if (getLayoutInflater().getFactory() == null) {
getLayoutInflater().setFactory(this);
}
super.onCreate(savedInstanceState);
NonConfigurationInstances nc = (NonConfigurationInstances)
getLastNonConfigurationInstance();
if (nc != null) {
mAllLoaderManagers = nc.loaders;
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
}
mFragments.dispatchCreate();
}
Это выбор дизайна API. Он сохраняет поверхность API меньше (меньше методов) и является стандартным шаблоном ( http://en.wikipedia.org/wiki/Decorator_pattern).