Here is my onCreate()
method:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
currentMeasurementType = DEFAULT_TYPE;
final DataBaseHandler handler = new DataBaseHandler(getApplicationContext());
SQLiteDatabase db = handler.getWritableDatabase();
//Spinner for the measurement types
final Spinner measurementTypesSpinner = (Spinner) findViewById(R.id.MeasurementTypes);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,
handler.getMeasurementTypes());
adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
measurementTypesSpinner.setAdapter(adapter);
measurementTypesSpinner.setOnItemSelectedListener(this);
//Spinner for the measurement sub types
final Spinner measurementSubTypesSpinner = (Spinner) findViewById(R.id.MeasurementSubValues);
try {
ArrayAdapter<String> subAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,
handler.getMeasurementSubType(DEFAULT_TYPE));
subAdapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
measurementSubTypesSpinner.setAdapter(subAdapter);
//measurementSubTypesSpinner.setOnItemSelectedListener(this); TODO
} catch(NonExistentMeasurementTypeException ex) {
Log.d("failed to initialise the spinner for the measurement units", ex.getMessage());
}
//the value from which the user is converting from
EditText value = (EditText) findViewById(R.id.unit_value);
value.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
unitValue = charSequence.toString();
MeasurementType mType =
MeasurementType.getMeasurementType(measurementTypesSpinner.getSelectedItem().toString());
String unitName = measurementSubTypesSpinner.getSelectedItem().toString();
String unitValue = charSequence.toString();
//create the converter
Converter converter = new Converter(mType, unitName, unitValue);
//convert the values
ArrayList<Unit> convertedValues = converter.convert();
//update the list view adapter
updateUnitAdapter(convertedValues);
}
@Override
public void afterTextChanged(Editable editable) {
//nothing here
}
});
//ListView
ListView unitsView = (ListView) findViewById(R.id.units_list);
unitsView.setItemsCanFocus(true);
MeasurementType type = handler.getMeasurementType(DEFAULT_TYPE);
final ArrayList<Unit> unitsConverted = new ArrayList<Unit>();
unitsConverted.addAll(Arrays.asList(type.getUnits()));
/**for some reason we need to do a clean up
* also going to set the unit values to zero
* for initialisation
*/
for(Unit u : unitsConverted) {
if(u == null) {
unitsConverted.remove(u);
} else {
u.setValue(0.00);
}
}
unitAdapter = new UnitListAdapter(this, unitsConverted, type);
unitsView.setAdapter(unitAdapter);
Button editList = (Button) findViewById(R.id.editList);
editList.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ArrayList<Unit> units = handler.getUnitsList(currentMeasurementType);
Intent i = new Intent(getApplicationContext(), MeasurementTypeListActivity.class);
i.putParcelableArrayListExtra("units", units);
i.putExtra("measurementType", currentMeasurementType);
startActivity(i);
}
});
}
here is my onResume()
method:
@Override
protected void onResume() {
super.onResume();
SharedPreferences prefs = this.getSharedPreferences(
"unitconverter", Context.MODE_PRIVATE);
DataBaseHandler handler = new DataBaseHandler(getApplicationContext());
//set the spinner for measurement type
Spinner measurementTypeSpinner = (Spinner) findViewById(R.id.MeasurementTypes);
ArrayAdapter adapter = (ArrayAdapter) measurementTypeSpinner.getAdapter();
int typePos = adapter.getPosition(prefs.getString("currentmeasurementtype", "acceleration"));
measurementTypeSpinner.setSelection(typePos);
//set the spinner for the measurement unit
Spinner measurementUnitSpinner = (Spinner) findViewById(R.id.MeasurementSubValues);
ArrayAdapter arrayAdapter = (ArrayAdapter) measurementUnitSpinner.getAdapter();
int unitPos = arrayAdapter.getPosition(prefs.getString("currentmeasurementunit", "centigal"));
measurementUnitSpinner.setSelection(unitPos);
//set the value
EditText value = (EditText) findViewById(R.id.unit_value);
value.setText(prefs.getString("value", "0.00"));
/**
* The list view stuff
*/
ListView unitsList = (ListView) findViewById(R.id.units_list);
unitsList.setItemsCanFocus(true);
MeasurementType mType = handler.getMeasurementType(prefs.getString("currentmeasurementtype", "acceleration"));
//create the converter
Converter converter = new Converter(MeasurementType.getMeasurementType(prefs.getString("currentmeasurementtype", "acceleration")), prefs.getString("currentmeasurementunit", "centigal"), prefs.getString("value", "0.00"));
//convert the values
ArrayList<Unit> convertedValues = converter.convert();
//update the current adapter
updateUnitAdapter(convertedValues);
}
here is the stack trace:
java.lang.RuntimeException: Unable to resume activity {com.example.UnitConverter/com.example.UnitConverter.MyActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2788)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.UnitConverter.MyActivity$1.onTextChanged(MyActivity.java:78)
at android.widget.TextView.sendOnTextChanged(TextView.java:7408)
at android.widget.TextView.setText(TextView.java:3816)
at android.widget.TextView.setText(TextView.java:3671)
at android.widget.EditText.setText(EditText.java:80)
at android.widget.TextView.setText(TextView.java:3646)
at com.example.UnitConverter.MyActivity.onResume(MyActivity.java:243)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192)
at android.app.Activity.performResume(Activity.java:5310)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2778)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
so it is trying to do this:
at com.example.UnitConverter.MyActivity$1.onTextChanged(MyActivity.java:78)
after which it goes here:
at com.example.UnitConverter.MyActivity.onResume(MyActivity.java:243)
when I look at line 78 I can see this:
String unitName = measurementSubTypesSpinner.getSelectedItem().toString();
so It is trying to set this variable and it looks like it is going to line 242 to do this and line 242 reads this:
EditText value = (EditText) findViewById(R.id.unit_value);
value.setText(prefs.getString("value", "0.00"));
These are actually line 241 and 242, before it is suggested that I haven't initialised the EditText
. But my thought was that trying to get the String from the preferences was returning null...because it might not have been saved.
From the docs for getSelectedItem
:
Returns The data corresponding to the currently selected item, or null if there is nothing selected.
My guess is that your spinner has nothing selected so you get a NPE when you try to call toString()
on the returned null
value. You need to check that you got something back and set a default value if it is null
.