views:

262

answers:

1

The following code does not work, and throws a RuntimeException caused by NullPointerException

public class ListFilteredActivity extends Activity {
    LinearLayout typeSelector = new LinearLayout(this) ;

    @Override
    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         ScrollView sv = new ScrollView(this);
         this.setContentView(sv);
         //this.typeSelector = new LinearLayout(this);
         this.typeSelector.setOrientation(LinearLayout.VERTICAL);
         sv.addView(this.typeSelector);
     }

When I moved the initialization of this.typeSelection inside onCreate() it works great.

    @Override
    public void onCreate(Bundle savedInstanceState) {
       ...
       this.typeSelector = new LinearLayout(this);
       ...
    }

Why is the null pointer error? The inline declaration in the first piece of code happens as soon as constructor is called, and then the onCreate() has access to the object, isn't it?

+1  A: 

LinearLayout requires you pass in a Context. This is an Android lifecycle object and not a Java object. When declaring and initializing the field directly, this will be initialized using the Java default constructor. However you'll only get a context once the onCreate lifecycle method occurs, which is much, much later and part of Android, not Java. So when you call the LinearLayout constructor with this, Android is expecting a reference to a Context, which you only get after the call to onCreate.

JRL
Yup! Just to expand upon this a bit - when you say `LinearLayout typeSelector = new LinearLayout(this)`, that is actually executing in the constructor of your `ListFilteredActivity`. You have not defined a constructor so a default (I am cheating a bit by saying default. it's not 100% correct, but good enough for me to get this point across) constructor is called. Inside of that default constructor the code `new LinearLayout(this)` is being executed. Likely `this` is a valid Java object, but has not been "prepared" by the android OS yet. AKA `this` is not yet a valid android Context. What . . .
Hamy
. . . is likely happening is that some method is being called on `this` inside of the LinearLayout constructor. That method is expecting to get some value that a valid Android Context would contain. However, `this` has not been setup as a valid android context object yet, so `this` is likely just returning the default for the requested value. The default is likely null. Then someone inside the `LinearLayout` ctor it is trying to make some method call on null, thinking it is a valid android context value. Hence `NullPointerException`. Hope that helps you understand!
Hamy