0

One of the requirements of basic Android development (according to the Google docs) is that when you override the activity's lifecycle methods (onCreate, onResume, onPause, etc.), you must call the parent's method first:

@Override
protected void onResume()
{
    super.onResume();
}

Why doesn't the Android API use a non-virtual interface pattern to enforce this behavior, rather than relying on developers to remember to do so?:

Android's Activity Base class could look something like this (crude example):

public class Activity
{
    public final void onResume()
    {
        // do important things here
        virtualOnResume();   
    }
    protected abstract void virtualOnResume();
}

Child class written by Android developer:

public class MainActivity extends Activity
{
    @Override
    protected void virtualOnResume()
    {
        // do custom stuff here, without needing to call super.onResume()
    }
}

I haven't encountered a case where I need to write any instructions prior to calling the super method. Is there any time we should NOT call the super method, or not call it first? If it truly must always be first for any particular method in the life cycle, what was the reason behind the design decision not to use a NVI pattern to enforce it?

UPDATE: Been developing for Android for a while now, everyone at work uses my BaseActivity NVI class, and I've still yet to encounter a reason NOT to use an NVI for all lifecycle methods but the onCreate one. It appears that those who answered/commented in defense of the existing API design don't really have a justification, or don't really seem to understand what an NVI pattern is, so I'm going with the assumption that there is no good reason, that it's "just how it is."

orfdorf
  • 980
  • 9
  • 13
  • You don't have to call `super.onResume();` only calling `super.onCreate(...)` is mandatory in an `Activity`. Aside from that you can completely override any method. – Xaver Kapeller Jun 17 '14 at 17:28
  • The Google docs explicitly say to always call the super's method on all of the lifecycle methods. Regardless, even if it's just the onCreate method, the same question stands: Why not use NVI for that? – orfdorf Jun 17 '14 at 17:29
  • Can you link to the part of the documentation where it states this? Because it is only required for `onCreate()`. If you don't call `super.onCreate()` in `onCreate()` an exception will be thrown. – Xaver Kapeller Jun 17 '14 at 17:31
  • @XaverKapeller http://developer.android.com/reference/android/app/Activity.html#onResume() – Piotr Praszmo Jun 17 '14 at 17:32
  • In [Google's Android Developer section](http://developer.android.com/guide/components/activities.html), it says: Your implementation of these lifecycle methods must always call the superclass implementation before doing any work – orfdorf Jun 17 '14 at 17:34
  • Interesting, I didn't know that. My guess is to keep the code simple. I don't see a reason to do what you are suggesting here. There are hardly any reasons not to call a super method anyway and sometimes you may want to call it not at the start but later on in the method. The additional complexity from having extra methods for the implementation isn't worth it. The `Activity` class is a already a big mess, not need to make it more complicated. I assume your background is not in Java? Because that's a very non-java like thing you are suggesting :D – Xaver Kapeller Jun 17 '14 at 17:40
  • You don't have to remember it, it is there by default and there is no reason not to manually call it. If one uses your approach you just have additional restrictions. See @Banthers answer. I would argue that your approach makes it more complicated instead of simpler, there is nothing inherently wrong with having one additional line in your code. And it gives you more flexibility. A lot of things would be difficult or impossible with your approach. – Xaver Kapeller Jun 17 '14 at 18:03
  • How is it that you don't have to remember it? If you forget to do so, an exception is thrown. The only restriction my approach has is that the super's method now automatically executes first, which is what the docs tell you to do anyway. If there is ever a reason not to call it first, I had not encountered it yet. Banthar demonstrated such a scenario in his answer, and that's what I'm looking for - in what case is it necessary to do so despite repeatedly advising against it throughout the documentation, and if there is no such case, why not enforce it? – orfdorf Jun 17 '14 at 18:10
  • I'm not going to continue arguing here. I think I and the other answers already covered all the benefits of doing it this way. That little conceive of not having to call the super method just makes the code more complicated, and limits what you can do. And you really don't have to remember it, what IDE does not automatically insert the super call when you override a method? And when would you not want to call the super method anyway? Just look at Stack Overflow, there are hardly any questions about a missing super call. I see no benefits with your approach. – Xaver Kapeller Jun 17 '14 at 18:31

2 Answers2

4

You do not have to call super method as first statement of your method. Sometimes you might want to do stuff before and after super method is invoked.

See FragmentActivity for example:

@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();
}
Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
  • Good answer. This clearly goes against their own advice in the docs. Does such a situation exist for all other lifecycle methods too? – orfdorf Jan 08 '15 at 00:38
0

This is an API design choice. It keeps the API surface smaller (less methods) and is a standard pattern (http://en.wikipedia.org/wiki/Decorator_pattern).

HHK
  • 4,852
  • 1
  • 23
  • 40
  • And the NVI pattern is not because...? (http://en.wikipedia.org/wiki/Non-virtual_interface_pattern) – orfdorf Jan 08 '15 at 00:36