Java Android-无法启动activity ComponentInfo、Java.lang.NullPointerException
我完全是Android和Java的初学者。我创建了一个货币转换应用程序,当设备旋转时会崩溃 原代码:Java Android-无法启动activity ComponentInfo、Java.lang.NullPointerException,java,android,Java,Android,我完全是Android和Java的初学者。我创建了一个货币转换应用程序,当设备旋转时会崩溃 原代码: package typeone.jiahuei.currencyconvert; import android.content.res.Resources; import android.os.Bundle; import android.os.PersistableBundle; import android.support.v7.app.AppCompatActivity; import
package typeone.jiahuei.currencyconvert;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Spinner unitSpinner;
private EditText amountEditText;
private String itemSelected;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
amountEditText = (EditText) findViewById(R.id.MainAct_InputEditText);
unitSpinner = (Spinner) findViewById(R.id.MainAct_unit_spinner);
addItemsToUnitSpinner();
addListenerToUnitSpinner();
addListenerToAmountEditText();
}
private void addListenerToAmountEditText() {
amountEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
addListenerToUnitSpinner();
Quantity inputQuantity = new Quantity(getInputAmount(), Quantity.Unit.valueOf(itemSelected));
updateTextViews(inputQuantity);
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void addItemsToUnitSpinner() {
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> unitSpinnerAdapter = ArrayAdapter.createFromResource(this,
R.array.currency_type, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
unitSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
unitSpinner.setAdapter(unitSpinnerAdapter);
}
private void addListenerToUnitSpinner() {
unitSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
itemSelected = parent.getItemAtPosition(position).toString();
Quantity inputQuantity = new Quantity(getInputAmount(), Quantity.Unit.valueOf(itemSelected));
updateTextViews(inputQuantity);
Resources res = getResources();
String[] currencyNameArray = res.getStringArray(R.array.currency_name);
String toastString = "Converting " + currencyNameArray[position];
Toast.makeText(MainActivity.this, toastString, Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO lalala
}
});
}
private double getInputAmount() {
String inputString = amountEditText.getText().toString();
double inputAmount;
if ( inputString.isEmpty() || inputString.equals(".") ) {
inputAmount = 0;
} else {
inputAmount = Double.parseDouble(inputString);
}
return inputAmount;
}
private void updateTextViews(Quantity inputQuantity) {
String currentViewName;
for (Quantity.Unit unit : Quantity.Unit.values()) {
currentViewName = unit.name() + "_TextView";
int currentId = getResources().getIdentifier(currentViewName, "id",
MainActivity.this.getPackageName());
TextView currentTV = (TextView) findViewById(currentId);
currentTV.setText(inputQuantity.toQuantity(unit).toString());
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
在修改代码几个小时后,我发现通过更改下面的代码,错误得到了解决
public class MainActivity extends AppCompatActivity {
private Spinner unitSpinner;
private EditText amountEditText;
private static String itemSelected;
private void addListenerToAmountEditText() {
amountEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Quantity inputQuantity = new Quantity(getInputAmount(), Quantity.Unit.valueOf(MainActivity.itemSelected));
updateTextViews(inputQuantity);
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
我只在字符串变量的开头添加了“static”,并将itemSelected变量更改为MainActivity.itemSelected
我只是不明白为什么一开始就出现了错误,为什么做出这些更改可以解决这个问题?
顺便说一下,该单位是Quantity类中的枚举
非常感谢您的回答,谢谢 itemSelected在调用onTextChanged时仍然为空我知道这一点,但是为什么字符串在第一次启动时不为空?在调用onTextChanged之前,我尝试调用addListener方法,但它仍然返回null(当我旋转设备时)。只有在我将变量转换为静态变量后,错误才得以解决。谢谢,但您在onTextChangedBTW之前没有触发onItemSelected,只需调试它:添加日志或断点,然后查看它们的调用顺序以及在该点的不同值。我在开始时向字符串变量添加了“static”,并将onTextChanged中的itemSelected变量更改为MainActivity.itemSelected,错误消失了。你能告诉我它是如何解决这个问题的吗?我基本上是基于一种预感做出了这样的改变。我认为在旋转时会调用onCreate,但是出于我告诉过你的原因,它不会设置字符串。但是,在方向更改之前,您可能会执行一些其他操作。将其设置为“静态”时,可能会看到在方向更改之前设置的值。虽然它可能会在某些情况下修复崩溃,但也可能会破坏一些东西(您可能会看到错误的字符串),最重要的是,它可能无法修复问题。我知道当你第一次打开活动时,它仍然会发生。这就是为什么我建议您调试它
public class MainActivity extends AppCompatActivity {
private Spinner unitSpinner;
private EditText amountEditText;
private static String itemSelected;
private void addListenerToAmountEditText() {
amountEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Quantity inputQuantity = new Quantity(getInputAmount(), Quantity.Unit.valueOf(MainActivity.itemSelected));
updateTextViews(inputQuantity);
}
@Override
public void afterTextChanged(Editable s) {
}
});
}