-1
我是Android和Java的初學者。我創建了一個貨幣轉換應用程序,該應用程序在設備旋轉時崩潰。Java Android - 無法啓動活動ComponentInfo,java.lang.NullPointerException
原始代碼:
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);
}
}
的日誌是:
10:44:19.769 32467-32467/typeone.jiahuei.currencyconvert E/AndroidRuntime: FATAL EXCEPTION: main
Process: typeone.jiahuei.currencyconvert, PID: 32467
java.lang.RuntimeException: Unable to start activity ComponentInfo{typeone.jiahuei.currencyconvert/typeone.jiahuei.currencyconvert.MainActivity}: java.lang.NullPointerException: name == null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
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: name == null
at java.lang.Enum.valueOf(Enum.java:189)
at typeone.jiahuei.currencyconvert.Quantity$Unit.valueOf(Quantity.java:13)
at typeone.jiahuei.currencyconvert.MainActivity$1.onTextChanged(MainActivity.java:50)
at android.widget.TextView.sendOnTextChanged(TextView.java:7991)
at android.widget.TextView.setText(TextView.java:4345)
at android.widget.TextView.setText(TextView.java:4199)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4174)
at android.widget.TextView.onRestoreInstanceState(TextView.java:4067)
at android.view.View.dispatchRestoreInstanceState(View.java:14746)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127)
at android.view.View.restoreHierarchyState(View.java:14724)
at com.android.internal.policy.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2035)
at android.app.Activity.onRestoreInstanceState(Activity.java:1004)
at android.app.Activity.performRestoreInstanceState(Activity.java:959)
at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1163)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2389)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
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)
用了幾個小時的代碼搞亂後,我發現,通過更改下面的代碼,錯誤就解決了。
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) {
}
});
}
我只加「靜態」到字符串變量的開始,改變了itemSelected變量MainActivity.itemSelected。
我只是不明白爲什麼錯誤發生在第一位,以及爲什麼進行這些更改可以解決問題? 順便說一下,Unit是Quantity類中的枚舉。
任何答案非常感謝,謝謝!
我意識到這一點,但爲什麼字符串不是null時它是第一次啓動? 我試圖在調用onTextChanged之前調用addListener方法,但它仍然返回null(當我旋轉設備時)。 只有在將變量變爲靜態變量後,才能解決錯誤。謝謝 –
但你沒有觸發onTextChanged之前的選擇 – Gavriel
BTW只是調試它:要麼添加日誌,或斷點,看看他們叫什麼順序,並在這一點上有什麼不同的值 – Gavriel