Reputation: 25
My app crashes every time, whenever i use Cursor object to retrieve data from database. What precaution i must take for this? Please help
In this example, i have a simple form and a submit button. after submission, a list of train name will be displayed in the spinner.
Errors
02-14 00:38:48.428: E/AndroidRuntime(456): FATAL EXCEPTION: main
02-14 00:38:48.428: E/AndroidRuntime(456): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.spinnerexample/com.example.spinnerexample.MainActivity}: java.lang.NullPointerException02-14 00:38:48.428: E/AndroidRuntime(456): atandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.os.Handler.dispatchMessage(Handler.java:99)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.os.Looper.loop(Looper.java:123)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.app.ActivityThread.main(ActivityThread.java:3683)
02-14 00:38:48.428: E/AndroidRuntime(456): at java.lang.reflect.Method.invokeNative(Native Method)
02-14 00:38:48.428: E/AndroidRuntime(456): at java.lang.reflect.Method.invoke(Method.java:507)
02-14 00:38:48.428: E/AndroidRuntime(456): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-14 00:38:48.428: E/AndroidRuntime(456): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-14 00:38:48.428: E/AndroidRuntime(456): at dalvik.system.NativeStart.main(Native Method)
02-14 00:38:48.428: E/AndroidRuntime(456): Caused by: java.lang.NullPointerException
02-14 00:38:48.428: E/AndroidRuntime(456): at com.example.spinnerexample.MainActivity.onCreate(MainActivity.java:42)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-14 00:38:48.428: E/AndroidRuntime(456): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
02-14 00:38:48.428: E/AndroidRuntime(456): ... 11 more
My Cursor Object java file
public class AddTrains {
private static final int DB_VERSION = 1;
private static final String DB_NAME = "mydb";
private static final String TABLE_NAME = "trains";
private static final String KEY_ID = "_id";
private static final String KEY_TRAIN_NAME = "train_name";
private static final String KEY_TRAIN_NUMBER = "train_number";
private static final String KEY_HALT1 = "halt1";
private static final String KEY_HALT2 = "halt2";
private static final String KEY_HALT3 = "halt3";
private static final String KEY_HALT4 = "halt4";
private static final String KEY_HALT5 = "halt5";
private DBHelper ourHelper;
private final Context context;
private SQLiteDatabase ourDatabase;
private static final class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" +
KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_TRAIN_NAME + " TEXT NOT NULL, " +
KEY_TRAIN_NUMBER + " TEXT NOT NULL, " +
KEY_HALT1 + " TEXT NOT NULL, " +
KEY_HALT2 + " TEXT NOT NULL, " +
KEY_HALT3 + " TEXT NOT NULL, " +
KEY_HALT4 + " TEXT NOT NULL, " +
KEY_HALT5 + " TEXT NOT NULL); "
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
public AddTrains(Context c){
context = c;
}
public AddTrains open() throws SQLException{
ourHelper = new DBHelper(context);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close(){
ourHelper.close();
}
public long createEntry(String tname, int tnumber, String stop1,
String stop2, String stop3, String stop4, String stop5) {
// TODO Auto-generated method stub
ContentValues cv = new ContentValues();
cv.put(KEY_TRAIN_NAME, tname);
cv.put(KEY_TRAIN_NUMBER, tnumber);
cv.put(KEY_HALT1, stop1);
cv.put(KEY_HALT2, stop2);
cv.put(KEY_HALT3, stop3);
cv.put(KEY_HALT4, stop4);
cv.put(KEY_HALT5, stop5);
return ourDatabase.insert(TABLE_NAME, null, cv);
}
public Set<String> getAllData() {
// TODO Auto-generated method stub
Set<String> set = new HashSet<String>();
String selectQuery = "select * from " + TABLE_NAME;
Cursor cursor = ourDatabase.rawQuery(selectQuery, null);
Log.d("Count",cursor.getCount()+"");
if(cursor.getCount() > 0){
if (cursor.moveToFirst()) {
do {
set.add(cursor.getString(1));
} while (cursor.moveToNext());
}
}
cursor.close();
return set;
}
}
Mainactivity file
public class MainActivity extends Activity implements OnClickListener {
EditText train_name, train_number, halt1, halt2, halt3, halt4, halt5;
Button submit;
Spinner spinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
train_name = (EditText) findViewById(R.id.train_name);
train_number = (EditText) findViewById(R.id.train_no);
halt1 = (EditText) findViewById(R.id.halt1);
halt2 = (EditText) findViewById(R.id.halt2);
halt3 = (EditText) findViewById(R.id.halt3);
halt4 = (EditText) findViewById(R.id.halt4);
halt5 = (EditText) findViewById(R.id.halt5);
spinner = (Spinner) findViewById(R.id.spinner1);
submit.setOnClickListener(this);
AddTrains db = new AddTrains(this);
db.open();
Set<String> set = db.getAllData();
//Convert set into list
List<String> list = new ArrayList<String>(set);
//Sort Data Alphabetical order
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
return lhs.compareTo(rhs);
}
});
ArrayAdapter adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View v, int position,long id) {
String name = parent.getItemAtPosition(position).toString();
Toast.makeText(getApplicationContext(), "You Selected: "+ name, Toast.LENGTH_LONG ).show();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
db.close();
}
public void onClick(View v){
switch(v.getId()){
case R.id.button1:
boolean DidItWorked = true;
try{
String tname = train_name.getText().toString();
int tnumber = Integer.parseInt(train_number.getText().toString());
String stop1 = halt1.getText().toString();
String stop2 = halt2.getText().toString();
String stop3 = halt3.getText().toString();
String stop4 = halt4.getText().toString();
String stop5 = halt5.getText().toString();
AddTrains at = new AddTrains(this);
at.open();
at.createEntry(tname, tnumber, stop1, stop2, stop3, stop4, stop5);
at.close();
}catch(SQLiteException e){
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Upvotes: 0
Views: 1302
Reputation: 18873
Multiple problems:
Delcared button, set a listener but never created or find in xml.
Button submit;
submit.setOnClickListener(this);
Are you missing
submit=(Button)findViewById(R.id.awesome_button);
Are you sure this is what you mean?
while (cursor.moveToNext());
Did you check on Line 42? Please point where this line is
02-14 00:38:48.428: E/AndroidRuntime(456): Caused by: java.lang.NullPointerException
02-14 00:38:48.428: E/AndroidRuntime(456): at com.example.spinnerexample.MainActivity.onCreate(MainActivity.java:42)
Upvotes: 1
Reputation: 415
If you solved this, it would be good to post what you figured out for others (like me :) to learn from.
One thing I always do is put a Log.d msg wherever there is a catch block. For instance, you have
public void onClick(View v){
switch(v.getId()){
case R.id.button1:
boolean DidItWorked = true;
try{
String tname = train_name.getText().toString();
// snip ...
at.createEntry(tname, tnumber, stop1, stop2, stop3, stop4, stop5);
at.close();
}catch(SQLiteException e){
}
So what happens if it bombs there ? You get a stack trace dump - and your app crashes on the user. I'd suggest this:
}catch(SQLiteException e){
Log.d ("OMG", "button1::onClick() caught exception: " + e.toString() ) ;
// do nothing or some clean up ... but app will likely keep chugging along
}
Upvotes: 1
Reputation: 93708
You're dereferencing a null pointer. Either ourDatabase is null, or the rawQuery is returning null. Check line 42, if its the query statement it's the database is null, otherwise its the cursor. How to fix it depends on what you find out there.
Upvotes: 0