-3

I wanna know why when I declare a member variable and assign it a value linking it with a button, the app keeps crashing. However, when I declared it without a value and gave it the value inside the onCreate method, the app worked perfectly fine.

Crashes when:-

public class MainActivity extends AppCompatActivity {
    Button buttonTrue = findViewById(R.id.buttonTrue);
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buttonTrue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();

            }
        });
}

Doesn't Crash when :-

public class MainActivity extends AppCompatActivity {
    Button buttonTrue;
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buttonTrue  = findViewById(R.id.buttonTrue);
        buttonTrue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();

            }
        });
}
Zoe
  • 27,060
  • 21
  • 118
  • 148
  • 1
    Seems like you cannot initialize a `Button` **before** `onCreate()` is called, doesn't it? – deHaar Jun 05 '19 at 09:30

2 Answers2

3

You cannot use findViewById() unless you actually set a layout to the Activity. Your app will crash because when the class is created first, there is no Button with ID R.id.buttonTrue as you've not set the layout.

You'll always get NullPointerException with what you're doing.

Correct way of finding the Views by ID is after they're available in the Activity view hierarchy after the setContentView(R.layout.activity_main) is executed.

You'll encounter the same NullPointerException if you try to find the same view before setContentView() is executed, i.e. if you try to do this.

protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button button = findViewById(R.id.your_button);
        //This will give NullPointerException as you're trying to find
        //button before activity gets any layout to work with
        setContentView(R.layout.activity_main);
}
Vedprakash Wagh
  • 3,595
  • 3
  • 12
  • 33
0

In the first code snippet, you have tried to do

Button buttonTrue = findViewById(R.id.buttonTrue);

As you can see, you are trying to findView before setting the setContentView, it is only after setContentView in the onCreate, does the activity and inflater knows which layout file, to work upon. In your case if you do this to your first code segment

  public class MainActivity extends AppCompatActivity {
    Button buttonTrue;
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buttonTrue= = findViewById(R.id.buttonTrue);
        buttonTrue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();

            }
        });
}

As you can see, I have just moved the findViewById in the right place, ie. after you specify the layout resource id through the setContentView method, things will work fine :-)

Ashish Kumar
  • 374
  • 4
  • 11