2016-01-22 130 views
-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類中的枚舉。

任何答案非常感謝,謝謝!

回答

0

itemSelected仍然爲null當你打電話給文字變化

+0

我意識到這一點,但爲什麼字符串不是null時它是第一次啓動? 我試圖在調用onTextChanged之前調用addListener方法,但它仍然返回null(當我旋轉設備時)。 只有在將變量變爲靜態變量後,才能解決錯誤。謝謝 –

+0

但你沒有觸發onTextChanged之前的選擇 – Gavriel

+0

BTW只是調試它:要麼添加日誌,或斷點,看看他們叫什麼順序,並在這一點上有什麼不同的值 – Gavriel

相關問題