Caoimhe
Caoimhe

Reputation: 9

Android Studio Runtime Errors

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

Answers (3)

Suhas
Suhas

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

Matt Clark
Matt Clark

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

Chris Stillwell
Chris Stillwell

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

Related Questions