我正在为学校的课堂项目开发一个计算器应用程序,但是在幕后似乎有些错误不是基于语法的。我尝试运行我的应用程序崩溃。我一直无法找到我的错误,但在点击提交按钮后它总是崩溃。我还没有一个应用程序完全拒绝运行。
的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.stins.calculator">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.example.stins.calculator.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
MainActivity.java
package com.example.stins.calculator;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.example.stins.calculator.Calculator;
import com.example.stins.calculator.CalculatorImpl;
import com.example.stins.calculator.Config;
import com.example.stins.calculator.Constants;
import com.example.stins.calculator.Formatter;
import com.example.stins.calculator.R;
import com.example.stins.calculator.Utils;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnLongClick;
import me.grantland.widget.AutofitHelper;
public class MainActivity extends SimpleActivity implements Calculator {@BindView(R.id.result)
TextView mResult;@BindView(R.id.formula)
TextView mFormula;
private static CalculatorImpl mCalc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
CalculatorImpl calc = new CalculatorImpl(this);
AutofitHelper.create(mResult);
AutofitHelper.create(mFormula);
}
@OnClick(R.id.btn_plus)
public void plusClicked() {
mCalc.handleOperation(Constants.PLUS);
}
@OnClick(R.id.btn_minus)
public void minusClicked() {
mCalc.handleOperation(Constants.MINUS);
}
@OnClick(R.id.btn_multiply)
public void multiplyClicked() {
mCalc.handleOperation(Constants.MULTIPLY);
}
@OnClick(R.id.btn_divide)
public void divideClicked() {
mCalc.handleOperation(Constants.DIVIDE);
}
@OnClick(R.id.btn_modulo)
public void moduloClicked() {
mCalc.handleOperation(Constants.MODULO);
}
@OnClick(R.id.btn_power)
public void powerClicked() {
mCalc.handleOperation(Constants.POWER);
}
@OnClick(R.id.btn_root)
public void rootClicked() {
mCalc.handleOperation(Constants.ROOT);
}
@OnClick(R.id.btn_clear)
public void clearClicked() {
mCalc.handleClear();
}
@OnLongClick(R.id.btn_clear)
public boolean clearLongClicked() {
mCalc.handleReset();
return true;
}
@OnClick(R.id.btn_equals)
public void equalsClicked() {
mCalc.handleEquals();
}
@OnClick({
R.id.btn_decimal,
R.id.btn_0,
R.id.btn_1,
R.id.btn_2,
R.id.btn_3,
R.id.btn_4,
R.id.btn_5,
R.id.btn_6,
R.id.btn_7,
R.id.btn_8,
R.id.btn_9
})
public void numpadClick(View view) {
numpadClicked(view.getId());
}
public void numpadClicked(int id) {
mCalc.numpadClicked(id);
}
@Override
public void setValue(String value) {
mResult.setText(value);
}
// used only by Robolectric
@Override
public void setValueDouble(double d) {
mCalc.setValue(Formatter.doubleToString(d));
mCalc.setLastKey(Constants.DIGIT);
}
public void setFormula(String value) {
mFormula.setText(value);
}
public CalculatorImpl getCalc() {
return mCalc;
}
}
CalcImpl.java
package com.example.stins.calculator;
public class CalculatorImpl {
private String mDisplayedValue;
private String mDisplayedFormula;
private String mLastKey;
private String mLastOperation;
private Calculator mCallback;
private boolean mIsFirstOperation;
private boolean mResetValue;
private double mBaseValue;
private double mSecondValue;
public CalculatorImpl(Calculator calculator) {
mCallback = calculator;
resetValues();
setValue("0");
setFormula("");
}
public CalculatorImpl(Calculator calculatorInterface, String value) {
mCallback = calculatorInterface;
resetValues();
mDisplayedValue = value;
setFormula("");
}
private void resetValueIfNeeded() {
if (mResetValue) mDisplayedValue = "0";
mResetValue = false;
}
private void resetValues() {
mBaseValue = 0;
mSecondValue = 0;
mResetValue = false;
mLastKey = "";
mLastOperation = "";
mDisplayedValue = "";
mDisplayedFormula = "";
mIsFirstOperation = true;
}
public void setValue(String value) {
mCallback.setValue(value);
mDisplayedValue = value;
}
private void setFormula(String value) {
mCallback.setFormula(value);
mDisplayedFormula = value;
}
private void updateFormula() {
final String first = Formatter.doubleToString(mBaseValue);
final String second = Formatter.doubleToString(mSecondValue);
final String sign = getSign(mLastOperation);
if (sign.equals("√")) {
setFormula(sign + first);
} else if (!sign.isEmpty()) {
setFormula(first + sign + second);
}
}
public void setLastKey(String mLastKey) {
this.mLastKey = mLastKey;
}
public void addDigit(int number) {
final String currentValue = getDisplayedNumber();
final String newValue = formatString(currentValue + number);
setValue(newValue);
}
private String formatString(String str) {
// if the number contains a decimal, do not try removing the leading zero anymore, nor add group separator
// it would prevent writing values like 1.02
if (str.contains(".")) return str;
final double doubleValue = Formatter.stringToDouble(str);
return Formatter.doubleToString(doubleValue);
}
private void updateResult(double value) {
setValue(Formatter.doubleToString(value));
mBaseValue = value;
}
public String getDisplayedNumber() {
return mDisplayedValue;
}
public double getDisplayedNumberAsDouble() {
return Formatter.stringToDouble(getDisplayedNumber());
}
public String getDisplayedFormula() {
return mDisplayedFormula;
}
public void handleResult() {
mSecondValue = getDisplayedNumberAsDouble();
calculateResult();
mBaseValue = getDisplayedNumberAsDouble();
}
public void calculateResult() {
if (!mIsFirstOperation) updateFormula();
switch (mLastOperation) {
case Constants.PLUS:
updateResult(mBaseValue + mSecondValue);
break;
case Constants.MINUS:
updateResult(mBaseValue - mSecondValue);
break;
case Constants.MULTIPLY:
updateResult(mBaseValue * mSecondValue);
break;
case Constants.DIVIDE:
divideNumbers();
break;
case Constants.MODULO:
moduloNumbers();
break;
case Constants.POWER:
powerNumbers();
break;
case Constants.ROOT:
updateResult(Math.sqrt(mBaseValue));
break;
default:
break;
}
mIsFirstOperation = false;
}
private void divideNumbers() {
double resultValue = 0;
if (mSecondValue != 0) resultValue = mBaseValue / mSecondValue;
updateResult(resultValue);
}
private void moduloNumbers() {
double resultValue = 0;
if (mSecondValue != 0) resultValue = mBaseValue % mSecondValue;
updateResult(resultValue);
}
private void powerNumbers() {
double resultValue = Math.pow(mBaseValue, mSecondValue);
if (Double.isInfinite(resultValue) || Double.isNaN(resultValue)) resultValue = 0;
updateResult(resultValue);
}
public void handleOperation(String operation) {
if (mLastKey.equals(Constants.DIGIT)) handleResult();
mResetValue = true;
mLastKey = operation;
mLastOperation = operation;
if (operation.equals(Constants.ROOT)) calculateResult();
}
public void handleClear() {
final String oldValue = getDisplayedNumber();
String newValue = "0";
final int len = oldValue.length();
int minLen = 1;
if (oldValue.contains("-")) minLen++;
if (len > minLen) newValue = oldValue.substring(0, len - 1);
newValue = newValue.replaceAll("\\.$", "");
newValue = formatString(newValue);
setValue(newValue);
mBaseValue = Formatter.stringToDouble(newValue);
}
public void handleReset() {
resetValues();
setValue("0");
setFormula("");
}
public void handleEquals() {
if (mLastKey.equals(Constants.EQUALS)) calculateResult();
if (!mLastKey.equals(Constants.DIGIT)) return;
mSecondValue = getDisplayedNumberAsDouble();
calculateResult();
mLastKey = Constants.EQUALS;
}
public void decimalClicked() {
String value = getDisplayedNumber();
if (!value.contains(".")) value += ".";
setValue(value);
}
public void zeroClicked() {
String value = getDisplayedNumber();
if (!value.equals("0")) addDigit(0);
}
private String getSign(String lastOperation) {
switch (lastOperation) {
case Constants.PLUS:
return "+";
case Constants.MINUS:
return "-";
case Constants.MULTIPLY:
return "*";
case Constants.DIVIDE:
return "/";
case Constants.MODULO:
return "%";
case Constants.POWER:
return "^";
case Constants.ROOT:
return "√";
}
return "";
}
public void numpadClicked(int id) {
if (mLastKey.equals(Constants.EQUALS)) mLastOperation = Constants.EQUALS;
mLastKey = Constants.DIGIT;
resetValueIfNeeded();
switch (id) {
case R.id.btn_decimal:
decimalClicked();
break;
case R.id.btn_0:
zeroClicked();
break;
case R.id.btn_1:
addDigit(1);
break;
case R.id.btn_2:
addDigit(2);
break;
case R.id.btn_3:
addDigit(3);
break;
case R.id.btn_4:
addDigit(4);
break;
case R.id.btn_5:
addDigit(5);
break;
case R.id.btn_6:
addDigit(6);
break;
case R.id.btn_7:
addDigit(7);
break;
case R.id.btn_8:
addDigit(8);
break;
case R.id.btn_9:
addDigit(9);
break;
default:
break;
}
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/calculator_holder"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.stins.calculator.MainActivity">
<TextView
android:id="@+id/formula"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2.1"
android:fontFamily="sans-serif-light"
android:gravity="right|bottom"
android:maxLines="1"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/formula_text_size"/>
<TextView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.8"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical|right"
android:maxLines="1"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:text="0"
android:textSize="@dimen/display_text_size"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="horizontal">
<Button
android:id="@+id/btn_modulo"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="mod"
android:textAllCaps="false"
android:textSize="@dimen/mod_text_size"/>
<Button
android:id="@+id/btn_power"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="^"/>
<Button
android:id="@+id/btn_root"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="√"/>
<Button
android:id="@+id/btn_clear"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="C"/>
<Button
android:id="@+id/btn_reset"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="AC"
android:visibility="gone"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="horizontal">
<Button
android:id="@+id/btn_7"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="7"/>
<Button
android:id="@+id/btn_8"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="8"/>
<Button
android:id="@+id/btn_9"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="9"/>
<Button
android:id="@+id/btn_divide"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="÷"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="horizontal">
<Button
android:id="@+id/btn_4"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="4"/>
<Button
android:id="@+id/btn_5"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="5"/>
<Button
android:id="@+id/btn_6"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="6"/>
<Button
android:id="@+id/btn_multiply"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="*"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="horizontal">
<Button
android:id="@+id/btn_1"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="1"/>
<Button
android:id="@+id/btn_2"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="2"/>
<Button
android:id="@+id/btn_3"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="3"/>
<Button
android:id="@+id/btn_minus"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="-"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="horizontal">
<Button
android:id="@+id/btn_0"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0"/>
<Button
android:id="@+id/btn_decimal"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="."/>
<Button
android:id="@+id/btn_equals"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="="/>
<Button
android:id="@+id/btn_plus"
style="@style/MyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="+"/>
</LinearLayout>
</LinearLayout>
logcat的
02-11 14:27:36.485 5006-5006/com.example.stins.calculator E/AndroidRuntime:
FATAL EXCEPTION: main
Process: com.example.stins.calculator, PID: 5006
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.stins.calculator/com.example.stins.calculator.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.widget.TextView.getContext()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
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.content.Context android.widget.TextView.getContext()' on a null object reference
at me.grantland.widget.AutofitHelper.<init>(AutofitHelper.java:246)
at me.grantland.widget.AutofitHelper.create(AutofitHelper.java:62)
at me.grantland.widget.AutofitHelper.create(AutofitHelper.java:46)
at com.example.stins.calculator.MainActivity.onCreate(MainActivity.java:40)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
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)
如果可能,有人会知道如何提供帮助吗?
我也包含了我的logcat
答案 0 :(得分:1)
检查以确保annotationProcessor
中设置了butterknife
build.gradle
dependencies
。您应该在annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
下面有一行如下所示:
{{1}}。
添加运行build-&gt; rebuild项目后。