简体   繁体   中英

Android - Can't find what's throwing NullPointerException

I'm trying to find out what's throwing a NullPointerException in my app but, after 2 hours I still got nothing. Can someone help me?

The Main code:

public class Main extends Activity implements OnClickListener {

    TextView tv_screen;

    static final String digits = "0123456789.";

    Boolean userIsInTheMiddleOfTypingANumber = false;

    Solver solver;

    DecimalFormat df = new DecimalFormat("@###########");

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        /* REMOVE TITLE BAR */

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        /* REMOVE NOTIFICATION BAR (AKA FULL SCREEN) */

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        df.setMinimumFractionDigits(0);
        df.setMinimumIntegerDigits(1);
        df.setMaximumIntegerDigits(8);

        tv_screen = (TextView) findViewById(R.id.tv_screen);

        findViewById(R.id.button_1).setOnClickListener(this);
        findViewById(R.id.button_2).setOnClickListener(this);
        findViewById(R.id.button_3).setOnClickListener(this);
        findViewById(R.id.button_4).setOnClickListener(this);
        findViewById(R.id.button_5).setOnClickListener(this);
        findViewById(R.id.button_6).setOnClickListener(this);
        findViewById(R.id.button_7).setOnClickListener(this);
        findViewById(R.id.button_8).setOnClickListener(this);
        findViewById(R.id.button_9).setOnClickListener(this);
        findViewById(R.id.button_0).setOnClickListener(this);

        findViewById(R.id.button_multiply).setOnClickListener(this);
        findViewById(R.id.button_divide).setOnClickListener(this);
        findViewById(R.id.button_minus).setOnClickListener(this);
        findViewById(R.id.button_sum).setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

        String buttonPressed = ((Button) v).getText().toString();

        if (digits.contains(buttonPressed)) {

            // digit was pressed
            if (userIsInTheMiddleOfTypingANumber) {

                if (buttonPressed.equals(".") && tv_screen.getText().toString().contains(".")) {
                    // ERROR PREVENTION
                    // Eliminate entering multiple decimals
                } else {
                    tv_screen.append(buttonPressed);
                }

            } else {

                if (buttonPressed.equals(".")) {
                    // ERROR PREVENTION
                    // This will avoid error if only the decimal is hit before an operator, by placing a leading zero
                    // before the decimal
                    tv_screen.setText(0 + buttonPressed);
                } else {
                    tv_screen.setText(buttonPressed);
                }

                userIsInTheMiddleOfTypingANumber = true;
            }

        } else {
            // operation was pressed
            if (userIsInTheMiddleOfTypingANumber) {

                //Log.w("TAG", "thickness round:" + yyy);

                solver.setOperand(Double.parseDouble(tv_screen.getText().toString()));
                userIsInTheMiddleOfTypingANumber = false;

            }

            solver.performOperation(buttonPressed);
            tv_screen.setText(df.format(solver.getResult()));

        }

    }

}

The Solver code:

public class Solver {

    // 3 + 6 = 9
    // 3 & 6 are called the operand.
    // The + is called the operator.
    // 9 is the result of the operation.

    private double mOperand;
    private double mWaitingOperand;
    private String mWaitingOperator;
    private double mCalculatorMemory;

    // operator types
    public static final String ADD = "+";
    public static final String SUBTRACT = "-";
    public static final String MULTIPLY = "x";
    public static final String DIVIDE = "/";

    public static final String CLEAR = "C" ;
    public static final String CLEARMEMORY = "MC";
    public static final String ADDTOMEMORY = "M+";
    public static final String SUBTRACTFROMMEMORY = "M-";
    public static final String RECALLMEMORY = "MR";
    public static final String SQUAREROOT = "√";
    public static final String SQUARED = "x²";
    public static final String INVERT = "1/x";
    public static final String TOGGLESIGN = "+/-";
    public static final String SINE = "sin";
    public static final String COSINE = "cos";
    public static final String TANGENT = "tan";

    // public static final String EQUALS = "=";

    // constructor
    public Solver() {
        // initialize variables upon start
        mOperand = 0;
        mWaitingOperand = 0;
        mWaitingOperator = "";
        mCalculatorMemory = 0;
    }

    public void setOperand(double operand) {
        mOperand = operand;
    }

    public double getResult() {
        return mOperand;
    }

    // used on screen orientation change
    public void setMemory(double calculatorMemory) {
        mCalculatorMemory = calculatorMemory;
    }

    // used on screen orientation change
    public double getMemory() {
        return mCalculatorMemory;
    }

    public String toString() {
        return Double.toString(mOperand);
    }

    protected double performOperation(String operator) {

        /*
        * If you are using Java 7, then you can use switch in place of if statements
        *
        *     switch (operator) {
        *     case CLEARMEMORY:
        *         calculatorMemory = 0;
        *         break;
        *     case ADDTOMEMORY:
        *         calculatorMemory = calculatorMemory + operand;
        *         break;
        *     etc...
        *     }
        */

        if (operator.equals(CLEAR)) {
            mOperand = 0;
            mWaitingOperator = "";
            mWaitingOperand = 0;
            // mCalculatorMemory = 0;
        } else if (operator.equals(CLEARMEMORY)) {
            mCalculatorMemory = 0;
        } else if (operator.equals(ADDTOMEMORY)) {
            mCalculatorMemory = mCalculatorMemory + mOperand;
        } else if (operator.equals(SUBTRACTFROMMEMORY)) {
            mCalculatorMemory = mCalculatorMemory - mOperand;
        } else if (operator.equals(RECALLMEMORY)) {
            mOperand = mCalculatorMemory;
        } else if (operator.equals(SQUAREROOT)) {
            mOperand = Math.sqrt(mOperand);

        } else if (operator.equals(SQUARED)) {
            mOperand = mOperand * mOperand;

        } else if (operator.equals(INVERT)) {
            if (mOperand != 0) {
                mOperand = 1 / mOperand;
            }
        } else if (operator.equals(TOGGLESIGN)) {
            mOperand = -mOperand;
        } else if (operator.equals(SINE)) {
            mOperand = Math.sin(Math.toRadians(mOperand)); // Math.toRadians(mOperand) converts result to degrees
        } else if (operator.equals(COSINE)) {
            mOperand = Math.cos(Math.toRadians(mOperand)); // Math.toRadians(mOperand) converts result to degrees
        } else if (operator.equals(TANGENT)) {
            mOperand = Math.tan(Math.toRadians(mOperand)); // Math.toRadians(mOperand) converts result to degrees
        } else {
            performWaitingOperation();
            mWaitingOperator = operator;
            mWaitingOperand = mOperand;
        }

        return mOperand;
    }

    protected void performWaitingOperation() {

        if (mWaitingOperator.equals(ADD)) {
            mOperand = mWaitingOperand + mOperand;
        } else if (mWaitingOperator.equals(SUBTRACT)) {
            mOperand = mWaitingOperand - mOperand;
        } else if (mWaitingOperator.equals(MULTIPLY)) {
            mOperand = mWaitingOperand * mOperand;
        } else if (mWaitingOperator.equals(DIVIDE)) {
            if (mOperand != 0) {
                mOperand = mWaitingOperand / mOperand;
            }
        }

    }
}

And the error:

01-03 00:46:02.420: E/AndroidRuntime(2558): FATAL EXCEPTION: main
01-03 00:46:02.420: E/AndroidRuntime(2558): java.lang.NullPointerException
01-03 00:46:02.420: E/AndroidRuntime(2558):     at com.pipeflexcalculator.calculator.Main.onClick(Main.java:103)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at android.view.View.performClick(View.java:4475)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at android.view.View$PerformClick.run(View.java:18786)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at android.os.Handler.handleCallback(Handler.java:730)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at android.os.Looper.loop(Looper.java:176)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at android.app.ActivityThread.main(ActivityThread.java:5419)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at java.lang.reflect.Method.invokeNative(Native Method)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at java.lang.reflect.Method.invoke(Method.java:525)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
01-03 00:46:02.420: E/AndroidRuntime(2558):     at dalvik.system.NativeStart.main(Native Method)

The logcat keeps pointing to the following line:

solver.setOperand(Double.parseDouble(tv_screen.getText().toString()));

I tried to change the "Double....." to "3.0" so I would be sure that it's not a problem in the tv_screen view, but still get the error.

Any idea?

You don't seem to instatiate solver anywhere so it's null in onClick() . Instantiate it somewhere before, for example in onCreate() or where you declare it:

Solver solver = new Solver();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM