0

I'm having slight problems understanding why a Null reference is flagged up:

package com.example.adam.bcapplication;

import android.app.Activity;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    //Define thread handler for the main UI thread

    //define global variable types
    int counter = 9;
    String strcounter;
    int buttoncounter = 0;
    String strbcounter;

    //Define the sensor Manager
    SensorManager sm;

    //Define the Motion Sensor objects
    Sensor accelerometer;
    Sensor gravity;
    Sensor gyroscope;
    Sensor uncalgyro;
    Sensor lineaccel;
    Sensor rotatevector;
    Sensor sigmotion;
    Sensor stepcounter;
    Sensor stepdetector;
    //Define the changing Motion Sensor text values

    //Define the position sensor objects
    Sensor gamerotatevector;

    //Define the changing Position sensor objects
    TextView gamerotatesense;
    //may need these
    final ImageButton button1 = (ImageButton) findViewById(R.id.motbut_unpressed);
    final ImageView topbar2 = (ImageView) findViewById(R.id.topbarmain);
    final ImageButton button2 = (ImageButton) findViewById(R.id.posbut_unpressed);
    final ImageButton button3 = (ImageButton) findViewById(R.id.envbut_unpressed);
    final LinearLayout bcfield = (LinearLayout) findViewById(R.id.babcocklayout);
    final ImageButton arrowup = (ImageButton) findViewById(R.id.uparrow);
    final ImageButton arrowdown = (ImageButton) findViewById(R.id.downarrow);
    final ImageView navbar = (ImageView) findViewById(R.id.infospace);
    final TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
    final TextView dynamicheader = (TextView) findViewById(R.id.dynamiched);
    private final Handler handler = new Handler();

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

        //Global counter variables
        counter = 9;
        strcounter = Integer.toString(counter);
        buttoncounter = 0;
        strbcounter = Integer.toString(buttoncounter);
        //Set Nav bar invisible for now
        arrowup.setVisibility(View.GONE);
        arrowdown.setVisibility(View.GONE);
        navbar.setVisibility(View.GONE);
        dynamictext.setVisibility(View.GONE);
        dynamicheader.setVisibility(View.GONE);
        sm = (SensorManager) getSystemService(SENSOR_SERVICE);


        button1.setOnClickListener( //This is for the motion button
                new ImageButton.OnClickListener() {
                    public void onClick(View v) {
                        new Thread(new button1task()).start();
                        dynamicheader.setText("Acceleration:");
                        //Now we need to register unregister the sensors and whatnot
                        accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
                        if (sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0) { // Add check to see if we have this sensor
                            sm.registerListener(MainActivity.this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
                        } else if (sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() == 0) {
                            dynamictext.setText("Sensor not detected");
                        }

                    }
                }
        );

followed by the runnable that's set like this:

    private class button1task implements Runnable { //This is button task on new thread inside UI
        public void run() {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    button1.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.motionbutton_pressed, null));
                    topbar2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.topbarmotion, null));
                    bcfield.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.logoandbarmotion, null));
                    //make sure the other two buttons are normal again
                    button2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.positionbutton_normal, null));
                    button3.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.envirobutton_normal, null));
                    //make the arrows and infospace appear
                    arrowup.setVisibility(View.VISIBLE);
                    arrowdown.setVisibility(View.VISIBLE);
                    navbar.setVisibility(View.VISIBLE);
                    //Dynamic text appearance
                    //set the text inside infospace
                    dynamicheader.setVisibility(View.VISIBLE);
                    dynamictext.setVisibility(View.VISIBLE);
                }
            });
        }

    }

This flags up this:

10-13 18:08:26.845    2345-2345/com.example.savag.babcockapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.savag.babcockapplication, PID: 2345
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.savag.babcockapplication/com.example.savag.babcockapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2327)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
            at android.app.Activity.findViewById(Activity.java:2090)
            at com.example.savag.babcockapplication.MainActivity.<init>(MainActivity.java:51)
            at java.lang.Class.newInstance(Native Method)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1067)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2317)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
10-13 18:08:31.597    2345-2345/? I/Process﹕ Sending signal. PID: 2345 SIG: 9

This error refers to the first (and probably all) declarations at the top. Now this is what I don't get.. did I not declare these correctly?
I said that button which is in the xml is a certain id. I mean it's a View or widget so I cannot set as int or string can I? Furthermore I don't see why this is a null pointer, am I not pointing to the button in the xml design?

I've seen several references to the word new but none of that seems to work for me. The strange thing is, without the handler, if all the code in the handler written in the button1 conditional along with the declarations... the code runs just fine.

hata
  • 11,633
  • 6
  • 46
  • 69
adambroni
  • 23
  • 3
  • 1
    Possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – Tom Oct 13 '15 at 18:47
  • Try moving all your findViewById() calls inside `onCreate()` method after setContentView! – Megh Vidani Oct 13 '15 at 18:48
  • Can you explain why you think that you can call `findViewById` before calling `setContentView(R.layout.activity_main)`? – Tom Oct 13 '15 at 18:50
  • @Tom you're asking me or him? – Megh Vidani Oct 13 '15 at 18:53
  • Ah, I assumed the UIThread would preload everything in some cases, especially global objects before content view is set – adambroni Oct 13 '15 at 18:53
  • @MeghVidani I would add a "@MeghVidani" if I would talk to you :). I meant OP. You just got noticed, because Stackoverflow notices OP and the last commentator above my comment. – Tom Oct 13 '15 at 18:54
  • oh... okay.. cheers! :) – Megh Vidani Oct 13 '15 at 18:56
  • So I can declare objects and create them before contentview is set but I cannot run a findviewbyid? why is that? Also does that not lock that content from the handler? – adambroni Oct 13 '15 at 19:00

1 Answers1

0

You should just declare the Different UI Views(button1 etc) and the assignment should happen in the onCreate method after calling setContentView because until you do setContentView for the activity the views are not available that is why they are null and whenever you will try to access them you will see the crash.

You need to replace these

final ImageButton button1 = (ImageButton) findViewById(R.id.motbut_unpressed);
final ImageView topbar2 = (ImageView) findViewById(R.id.topbarmain);
final ImageButton button2 = (ImageButton) findViewById(R.id.posbut_unpressed);
final ImageButton button3 = (ImageButton) findViewById(R.id.envbut_unpressed);
final LinearLayout bcfield = (LinearLayout) findViewById(R.id.babcocklayout);
final ImageButton arrowup = (ImageButton) findViewById(R.id.uparrow);
final ImageButton arrowdown = (ImageButton) findViewById(R.id.downarrow);
final ImageView navbar = (ImageView) findViewById(R.id.infospace);
final TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
final TextView dynamicheader = (TextView) findViewById(R.id.dynamiched);

with

ImageButton button1;
ImageView topbar2;
ImageButton button2;
ImageButton button3;
LinearLayout bcfield;
ImageButton arrowup;
ImageButton arrowdown;
ImageView navbar;
TextView dynamictext;
TextView dynamicheader;

and inside the onCreate function after the setContentView do the assignment like this

    button1 = (ImageButton) findViewById(R.id.motbut_unpressed);
    topbar2 = (ImageView) findViewById(R.id.topbarmain);
    button2 = (ImageButton) findViewById(R.id.posbut_unpressed);
    button3 = (ImageButton) findViewById(R.id.envbut_unpressed);
    bcfield = (LinearLayout) findViewById(R.id.babcocklayout);
    arrowup = (ImageButton) findViewById(R.id.uparrow);
    arrowdown = (ImageButton) findViewById(R.id.downarrow);
    navbar = (ImageView) findViewById(R.id.infospace);
    dynamictext = (TextView) findViewById(R.id.dynamictxt);
    dynamicheader = (TextView) findViewById(R.id.dynamiched);
pgiitu
  • 1,671
  • 1
  • 15
  • 23
  • Move this whole block into that method? Without doing anything else? – Tom Oct 13 '15 at 18:59
  • You should declare the `Views(button1 etc)` outside where they are as you would want to be able to access them from the class but the assignment of the views `button1 = (ImageButton) findViewById(R.id.motbut_unpressed);` should be inside the `oncreate`. – pgiitu Oct 13 '15 at 19:04
  • That's better. So don't you think you should write this in your answer? – Tom Oct 13 '15 at 19:08
  • Brilliant, thank you very much, does the handler not cause an issue? – adambroni Oct 13 '15 at 19:08
  • @adambroni about the handler I am not sure why you need it. Inside the `onClick` of the `button1` why can't you simple change the visibility and background of the different views? – pgiitu Oct 13 '15 at 19:16
  • @pgiitu The programs much much larger than this, having this settled in a different thread to lessen the load on the main thread, the entire program is reallllyyyyy slow, so i'm setting threads for all that and then loopers for the sensorlistens – adambroni Oct 13 '15 at 19:35