5

I am basically asking about the difference between these two approaches:

public class MyClass extends AppCompatActivity {
    private ObjectType mObject = new ObjectType();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // do stuff with mObject

and

public class MyClass extends AppCompatActivity {
    private ObjectType mObject;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mObject = new ObjectType();

I hope I'm being clear enough. I am struggling to understand when we'd want to choose one versus the other.

bighugedev
  • 379
  • 1
  • 3
  • 11
DoubleBass
  • 1,143
  • 4
  • 12
  • 29

2 Answers2

5

Functionally, nothing.

The first one will be created when the Activity object is created (new myClass() is called). The Android system does this at some point during creation.

The second one will be created when the system eventually calls onCreate().

The gotcha would be if you had an object that needs a Context in the constructor. You could do this for example:

public class myClass extends AppCompatActivity {
    private objectType object = new objectType(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //do stuff with object

And the app will suddenly crash because you most likely will try to extract resources from the Context that don't exist yet. (Remember, the Activity isn't created at this point).

So, if your object does have to use Context, then you have to create it at or after onCreate is called.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • 1
    So is `onCreate` technically the contructor of the activity? If not, what does the activity constructor do? Are you saying that `this` requires the constructor to have been called first? – DoubleBass Mar 10 '16 at 20:12
  • 1
    I'm not sure if it would help to think of it like that. More like a callback than a constructor. The Activity has a constructor (all classes do). However, all Activities *must* have a default constructor or the app will blow up (this is a requirement for this class. Not a requirement for all classes). The system creates an Activity instance. It builds it. Gives it the resources that it needs. Then when it's done building, it calls "onCreate()" on the Activity to tell you (the developer) that things are ready and good to go. That's when you do further setup that is custom to the activity. – DeeV Mar 10 '16 at 20:20
  • 1
    I suppose what I am asking is that is there some constructor called `myClass()` that gets called behind-the-scenes before `onCreate()` is called, and if so, what is it actually doing? – DoubleBass Mar 10 '16 at 20:26
  • Yes. It's the default constructor (no argument constructor). Classes aren't forced to implement this if they do nothing. In other words, the actual Activity constructor does nothing. You could override and create a default constructor yourself (`public myClass(){}`), but this is unconventional. 99.9% of the time you want to just rely on `onCreate()`. – DeeV Mar 10 '16 at 20:34
  • So would you say the second example is the safer option and that there's not really any good reason to do the first? (re: the OP examples) – DoubleBass Mar 10 '16 at 20:35
  • Should note that if you created another constructor like `public myClass(String name){}` then the app will crash because there is no longer a public constructor which is what the system is expecting. – DeeV Mar 10 '16 at 20:35
  • So if there are no explicitly-defined constructors present, it calls `myClass(){}` behind the scenes, which does nothing, but if you define one instead (whether it has arguments or not), it won't make that assumption and call anything, and therefore you should explicitly define the no-argument constructor if you're planning to explicitly define the argument-using constructor? – DoubleBass Mar 10 '16 at 20:37
  • No. There's not any good reason to do the first. The second option is more maintainable (in my opinion). – DeeV Mar 10 '16 at 20:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/105943/discussion-between-deev-and-doublebass). – DeeV Mar 10 '16 at 20:40
1

An Activity has a well defined lifecycle, as you probably know. It does not always matter if you create new instances in the constructor vs. onCreate, but you would definitely prefer onCreate in these circumstances:

  1. If the new object requires a valid Context, that is not available until onCreate(). You can't do this in the constructor.
  2. If you wish to proactively release the resource as soon as you don't need it any more, onDestroy provides a nice analog to onCreate with respect to the activity lifecycle. This may help objects be reclaimed faster than they would if they were created in the constructor and stored as "final". While this is not strictly necessary, it makes it clear to the reader that you wish to do work following the lifecycle of the Activity, not just the with the object instance itself.
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 1
    I am familiar with the basics of the lifecycle (create, pause, stop, destroy, etc), but I am not fully aware of how it all plays together on the backend exactly. When you say "you can't do this in the constructor" what are you referring to exactly (the member variable declaration section of the class)? As to your second point are you implying that it may be better to instantiate inside `onCreate()`? – DoubleBass Mar 10 '16 at 20:15
  • If you are creating an object that requires a valid Context (Activity is a Context), then you risk running into problems if that object constructor attempts to use the Activity you passed as if it were a valid Context. The first opportunity you have to use the Activity instance as a proper Context is in onCreate. If you don't need a Context at all to create the new object, it may not matter at all. – Doug Stevenson Mar 10 '16 at 20:16
  • Right but what I am asking is when the Activity instance first becomes usable (via "this") – DoubleBass Mar 10 '16 at 20:17
  • That's during onCreate. – Doug Stevenson Mar 10 '16 at 20:19
  • Is onCreate considered the constructor for an activity/context? Or is the constructor considered separate from this / does it do other things? Like for example if I were to just be coding regular Java (not in Android) and I tried to instantiate something requiring "this" in the declaration vs. the constructor, is the difference the same? (I am trying to understand what is actually going on under the hood here) – DoubleBass Mar 10 '16 at 20:19
  • onCreate is not a constructor. onCreate is a lifecycle method. The constructor is the same as the java definition for a constructor, which you normally do not provide for activity classes. But if you do provide one, it has to be a no-arg constructor if you expect it to be invoked. – Doug Stevenson Mar 10 '16 at 20:21
  • So let's say I defined/overloaded the constructor (which I assume gets called before onCreate) and I super() it to run the typical constructor procedures. Wouldn't the context be available at this point (even though we are still before onCreate)? – DoubleBass Mar 10 '16 at 20:22
  • It's not about availability. It's about validity. The Activity is not valid as a context until onCreate. – Doug Stevenson Mar 10 '16 at 20:24
  • I'm not sure I understand. What's the difference between available and valid? – DoubleBass Mar 10 '16 at 20:25
  • Don't assume that if an object exists that it's fully ready to operate. That's why there is a lifecycle defined. Valid in onCreate, invalid after onDestroy. – Doug Stevenson Mar 10 '16 at 20:26
  • So in general do you only instantiate in onCreate() (i.e. the second code example I listed) and not the first example? – DoubleBass Mar 10 '16 at 20:31
  • In general yes. It won't be surprising to experienced devs. – Doug Stevenson Mar 10 '16 at 21:08