11

This code, with the block at the top commented, runs successfully:

public class MainActivity extends AppCompatActivity {

    /*
    EditText username = (EditText)findViewById(R.id.editText_Username);
    EditText password = (EditText)findViewById(R.id.editText_Password);
    TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
    TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
    Button login=(Button)findViewById(R.id.button_Login);
    Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);
    */

    public void doLoginOnClick(View v)
    {
        String s1=username.getText().toString();
        inputdata.setText(s1);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab); 
        fab.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    } 
 
}

I am trying to capture id of component using

findViewById(R.id.***)

as you can see, I put this code in comment at the very beginning of the code.

EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
Button login=(Button)findViewById(R.id.button_Login);
Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);

If I remove the comment above and run it (both in emulator and real device), the program crashes immediately, I am surprised what's wrong here?

even I have tried to initialize the same thing using constructor.

But if I put it inside onCreate() there's no crash? Why?

I was trying to fetch info of username and password and display it to the textview in textView_Inputdata using

EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
inputdata.setText(username.getText.toString()+" "+password.getText.toString());

Is there better or easier way to do that?

Ryan M
  • 18,333
  • 31
  • 67
  • 74
000
  • 405
  • 5
  • 20
  • 1
    Without any stacktrace i bet its a nullPointerException caused by findViewById returning null caused by no layout loaded. Call it after setContentView(). – Nanoc Apr 06 '16 at 08:56

9 Answers9

21

Instance member variables are initialized when the instance itself is initialized. It's too early for findViewById()

Before onCreate() your activity does not yet have a Window that findViewById() needs internally. Before setContentView() (that you should be calling in onCreate()) there are no views to be found either.

Therefore init your view references in onCreate() and after setContentView().

laalto
  • 150,114
  • 66
  • 286
  • 303
4

Add this code

 EditText username =  findViewById(R.id.editText_Username);
 EditText password = findViewById(R.id.editText_Password);
 TextView inputdata = findViewById(R.id.textView_InputData);
 TextView welcome = findViewById(R.id.textView_Welcome);
 Button login = findViewById(R.id.button_Login);
 Button anotherLogin = findViewById(R.id.button_Login_Another);

in

onCreate(); 

method after

setContentView(R.layout.activity_main);
SmulianJulian
  • 801
  • 11
  • 33
Devanshu Dwivedi
  • 693
  • 2
  • 6
  • 18
1

Hey I see that you are defining and initialising the instance variables. What I do is I define the the instance variables - EditText username and then in the onCreate method I initialise them - username = (EditText) findViewById(R.id.editText_Username);

The reason you don't initialize the instance variables is because the elements are not ready until after the setContentView in onCreate method - I could be wrong with this, but my best practice is define the instance variable and then initialize them in the onCreate method

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Dan
  • 2,020
  • 5
  • 32
  • 55
1

Before setting setContentView() you are not able to initialize the view items.Because view will not be exists for activity at that time.

Keep the initializations in one separate method and call that method after setting the view to the activity.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
chaithu
  • 23
  • 5
1

You must call findViewById() after setContentView() in onCreate(), before that there isn't UI/Layout initialize thats why your findViewById() unable to find ids and throws NullPointerException.

public class MainActivity extends AppCompatActivity {

    public void doLoginOnClick(View v){
        String s1 = username . getText ().toString();
        inputdata.setText(s1);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar =(Toolbar) findViewById (R.id.toolbar);
        setSupportActionBar(toolbar);

        EditText username =(EditText) findViewById (R.id.editText_Username);
        EditText password =(EditText) findViewById (R.id.editText_Password);
        TextView inputdata =(TextView) findViewById (R.id.textView_InputData);
        TextView welcome =(TextView) findViewById (R.id.textView_Welcome);
        Button login =(Button) findViewById (R.id.button_Login);
        Button anotherLogin =(Button) findViewById (R.id.button_Login_Another);

        FloatingActionButton fab =(FloatingActionButton) findViewById (R.id.fab);
        fab.setOnClickListener(new View . OnClickListener ()
        {
            @Override
            public void onClick(View view)
            {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
            }
        });
    }
}
Upendra Shah
  • 2,218
  • 17
  • 27
1
  1. Initialize all your views after onCreate() Method

  2. Read More about activity lifecycle here

Manjeet deswal
  • 692
  • 2
  • 5
  • 18
1

Think of it this way - until you tell the activity which user interface layout(xml) to use, it will not know where to get those views from.
You would do setContentView(R.layout.your_xml) to tell the activity which layout to use as the user interface for the activity. You would do this in the onCreate callback because this is the callback to do 'one-time activity level set up' tasks. setContentView() is one such task. Once you do this, you can begin to access the views that are present within the layout file R.layout.your_xml.

onCreate(...) 
{
    ...
    setContentView(R.layout.your_xml) 
    // Ready to use the views from above xml. 
    findViewById(R.id.your_view) 
    ... 
}
1

setContentView() is responsible for inflating the layout of the activity. If any of the components are used before inflation of the layout, it will crash with a NullPointerException.

 @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        setContentView(R.layout.activity_layout);
        username =  findViewById(R.id.editText_Username);
        password = findViewById(R.id.editText_Password);
        inputdata = findViewById(R.id.textView_InputData);
        welcome = findViewById(R.id.textView_Welcome);
        login = findViewById(R.id.button_Login);
        anotherLogin = findViewById(R.id.button_Login_Another);
            
    }

You can still declare the variable in the beginning of the class, but you have to initialize it in onCreate.

Ryan M
  • 18,333
  • 31
  • 67
  • 74
Shubam Virdi
  • 144
  • 1
  • 4
  • I'm awarding the bounty to this answer because I think it's the best of the new answers. In particular, it includes the fact that the variables can be declared at the beginning of the class, but initialized in `onCreate`. – Ryan M Oct 20 '21 at 02:45
1

View Binding will help you prevent from these issues:

https://developer.android.com/topic/libraries/view-binding

Or declare the views on top, and initialize them after setContentView() in onCreate().

 public class MainActivity extends AppCompatActivity {

//Declare view on top
EditText username, password;
TextView inputdata,welcome;
Button login,notherLogin;


public void doLoginOnClick(View v)
{
    String s1=username.getText().toString();
    inputdata.setText(s1);
}

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //set view
    username =  findViewById(R.id.editText_Username);
    password = findViewById(R.id.editText_Password);
    inputdata = findViewById(R.id.textView_InputData);
    welcome = findViewById(R.id.textView_Welcome);
    login = findViewById(R.id.button_Login);
    anotherLogin = findViewById(R.id.button_Login_Another);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
} }
imdungnguyen
  • 216
  • 1
  • 3
  • 14