Teemonoob Teemonoob - 18 days ago 5
Android Question

Unable to start a List View activity due to invoking virtual method on null object reference. Tips?

sorry for the stupid and repetitive question. I am new to android programming and in progress of making an app which can scan QR Codes and save the data to an SQLite database and show it in a ListView of another activity.
Also, the ListView has a "search" function which enables the user to type text which will bring up a similar result (if found in the listview) from the items in the listview. Lastly, the delete function deletes the item from the ListView when the user taps on the item.

The application worked fine and opened the ListView Activity showing the ListView with the contents until I integrated the search and delete function.
The application states that I am trying to invoke a virtual method on a null object reference. I have looked up on how to solve it, but couldn't find anything.
Now it shows this error:

07-31 18:52:31.688 2900-2900/app.num.barcodescannerproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.num.barcodescannerproject, PID: 2900
java.lang.RuntimeException: Unable to start activity ComponentInfo{app.num.barcodescannerproject/app.num.barcodescannerproject.ListActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void app.num.barcodescannerproject.CustomCursorAdapter.changeCursor(android.database.Cursor)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void app.num.barcodescannerproject.CustomCursorAdapter.changeCursor(android.database.Cursor)' on a null object reference
at app.num.barcodescannerproject.ListActivity.onCreate(ListActivity.java:41)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442) 
at android.app.ActivityThread.access$800(ActivityThread.java:156) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:211) 
at android.app.ActivityThread.main(ActivityThread.java:5389) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) 
07-31 18:52:32.968 2900-2900/app.num.barcodescannerproject I/Process: Sending signal. PID: 2900 SIG: 9


Here is the code for the Activity which sends the Intent with the data to the ListView Activity:

public void saveOnClick (View saveButton){
String prescriptionName = scanResult.getText().toString();
if (prescriptionName.length() != 0) {
Intent newIntent = new Intent (this, ListActivity.class);
newIntent.putExtra("tag_person_name", prescriptionName);
startActivity(newIntent);
finish();
}
}


And this is the code for the ListActivity with the ListView, search and delete functions:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

databaseHelper = new PersonDatabaseHelper(this);

listView = (ListView) findViewById(R.id.list_data);
databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);


customAdapter = new CustomCursorAdapter(ListActivity.this, databaseHelper.getAllData());
listView.setAdapter(customAdapter);
Cursor cursor = databaseHelper.getAllData();


EditText myFilter = (EditText) findViewById(R.id.editText);
myFilter.addTextChangedListener(new TextWatcher() {

public void afterTextChanged(Editable s) {
}

public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}

public void onTextChanged(CharSequence s, int start,
int before, int count) {
customAdapter.getFilter().filter(s.toString());
}
});

customAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return databaseHelper.fetchDataByName(constraint.toString());
}
});
}


//public void onClickEnterData(View btnAdd) {
// startActivityForResult(new Intent(this, ResultActivity.class), ENTER_DATA_REQUEST_CODE);
//}

// @Override
//protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
// if (requestCode == ENTER_DATA_REQUEST_CODE && resultCode == RESULT_OK) {
// databaseHelper.insertData(data.getExtras().getString("tag_person_name"));
// customAdapter.changeCursor(databaseHelper.getAllData());
// }
// }
private OnItemClickListener listContentOnItemClickListener
= new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub


Cursor cursor = (Cursor) parent.getItemAtPosition(position);
final int item_id = cursor.getInt(cursor.getColumnIndex(PersonDatabaseHelper.PERSON_TABLE_COLUMN_ID));
String item_name = cursor.getString(cursor.getColumnIndex(PersonDatabaseHelper.PERSON_TABLE_COLUMN_NAME));


AlertDialog.Builder myDialog
= new AlertDialog.Builder(ListActivity.this);

myDialog.setTitle("Delete?");

TextView dialogTxt_id = new TextView(ListActivity.this);
ViewGroup.LayoutParams dialogTxt_idLayoutParams
= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialogTxt_id.setLayoutParams(dialogTxt_idLayoutParams);
dialogTxt_id.setText(String.valueOf(item_id));

TextView dialogC1_id = new TextView(ListActivity.this);
ViewGroup.LayoutParams dialogC1_idLayoutParams
= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialogC1_id.setLayoutParams(dialogC1_idLayoutParams);
dialogC1_id.setText(item_name);


LinearLayout layout = new LinearLayout(ListActivity.this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(dialogTxt_id);
layout.addView(dialogC1_id);
myDialog.setView(layout);

myDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
databaseHelper.delete_byID(item_id);
updateList();
}
});

myDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {

}
});

myDialog.show();
}
};

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
databaseHelper.close();
}


private void updateList() {

customAdapter.changeCursor(databaseHelper.getAllData());
}


}

According to what I see, the error is here, at the changeCursor:

databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);


I have also noticed that when I remove the changeCursor, the error will be shown at the setOnItemClickListener, stating that this virtual method is also being invoked on a null object reference.

Is there anything I can do about this? I have searched far and wide across many sites but cannot find the solution anywhere. Perhaps I'm blind.

UPDATE: Thank you for the help, I have realised that I did not initialise the customAdapter first. However, now that I did, I keep getting two exactly same NPE errors as the one with the customAdapater, except the first one is at the setOnItemClickListener and the other at the listView.setAdapter. Both are apparently also invoked on a null object. However this time, unlike with the customAdapter, I really can't spot the mistake. Any help?

Answer

You are initializing the CursorAdapter after its first use. This is wrong as you first need to create the CursorAdapter object before using it.

    ...

    databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
/* This line is moved from below to this place i.e before you use the changeCursor method on it*/
    customAdapter = new CustomCursorAdapter(ListActivity.this, databaseHelper.getAllData()); 
customAdapter.changeCursor(databaseHelper.getAllData());
    listView.setOnItemClickListener(listContentOnItemClickListener);

    ...

You are getting a Null Pointer Exception (NPE) because you are using an object that has not been created yet using the new operator

Comments