Reputation: 9
I keep getting this error in Android Studio:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{dit.assignment3/dit.assignment3.Timer}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
but I can't seem to find where in my code I'm going wrong, have tried commenting out all the findViewById's that I have but no luck.
Code:
public class Timer extends AppCompatActivity {
//declaring all items on page in class
EditText hoursIn = (EditText) findViewById(R.id.hoursET);
EditText minIn = (EditText) findViewById(R.id.minET);
Button start = (Button) findViewById(R.id.startButton);
Button stop = (Button) findViewById(R.id.stopButton);
TextView textViewTime = (TextView) findViewById(R.id.timeDisp);
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
// private GoogleApiClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
textViewTime.setText("00:00:30");
final CounterClass timer = new CounterClass(30000, 1000);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timer.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timer.cancel();
}
});
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
//client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
//@Override
/*public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Timer", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://dit.assignment3/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
@Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Timer Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://dit.assignment3/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}*/
public class CounterClass extends CountDownTimer {
/**
* @param millisInFuture The number of millis in the future from the call
* to {@link #start()} until the countdown is done and {@link #onFinish()}
* is called.
* @param countDownInterval The interval along the way to receive
* {@link #onTick(long)} callbacks.
*/
public CounterClass(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
long millis = millisUntilFinished;
String hrsminsec = String.format("%02:%02:%02", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toMinutes(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toSeconds(millis)))
);
textViewTime.setText(hrsminsec);
}
@Override
public void onFinish() {
textViewTime.setText("DONE");
}
}
}
Cheers
Upvotes: 0
Views: 121
Reputation: 65
You should assign all controls in onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
EditText hoursIn = (EditText) findViewById(R.id.hoursET);
EditText minIn = (EditText) findViewById(R.id.minET);
textViewTime.setText("00:00:30");
final CounterClass timer = new CounterClass(30000, 1000);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timer.start();
}
});
Upvotes: 0
Reputation: 28579
findViewById
cannot be called before both onCreate
and setContentView
.
Change around the following
EditText hoursIn;
public void onCreate(...){
...
setContentView(...);
hoursIn = (EditText) findViewById(R.id.hoursET);
...
}
The reason for this is that findViewById
is going to lookup an element that is currently on the display, before setting the content view, there is nothing to be found, thus leaving the result of findViewById
to be null.
Upvotes: 1
Reputation: 10547
You should put your findViewById
calls in your onCreate
you are trying to assign them before the Window has been created.
EditText hoursIn;
EditText minIn;
Button start;
Button stop;
TextView textViewTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
hoursIn = (EditText) findViewById(R.id.hoursET);
minIn = (EditText) findViewById(R.id.minET);
start = (Button) findViewById(R.id.startButton);
stop = (Button) findViewById(R.id.stopButton);
textViewTime = (TextView) findViewById(R.id.timeDisp);
Upvotes: 1