Search code examples
javaandroidnullpointerexceptionandroid-arrayadapter

ArrayAdapter NullPointerException Attempt to invoke virtual method on a null object reference


I can't figure out why it doesn't work.

java.lang.IllegalStateException: Could not execute method of the activity Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ArrayAdapter.add(java.lang.Object)' on a null object reference at com.example.buddy.test.TestDatabaseActivity.addButton(TestDatabaseActivity.java:31)

When Add button was clicking the app crashed but comment is in database.

TestDatabaseActivity.java

public class TestDatabaseActivity extends ListActivity {
private CommentsDataSource datasource;
private ArrayAdapter<Comment> adapter = (ArrayAdapter<Comment>) getListAdapter();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test_database);

    datasource = new CommentsDataSource(this);
    datasource.open();

    List<Comment> values = datasource.getAllComments();

    ArrayAdapter<Comment> adapter = new ArrayAdapter<Comment>(this, android.R.layout.simple_list_item_1, values);
    setListAdapter(adapter);
}

public void addButton(View view){
    Comment comment;
    comment = datasource.createComment("My comment");
    adapter.add(comment);
    adapter.notifyDataSetChanged();
}

public void deleteButton(View view){
    Comment comment;
    if (getListAdapter().getCount() > 0) {
        comment = (Comment) getListAdapter().getItem(0);
        datasource.deleteComment(comment);
        adapter.remove(comment);
    }
    adapter.notifyDataSetChanged();
}

@Override
protected void onResume() {
    datasource.open();
    super.onResume();
}

@Override
protected void onPause() {
    datasource.close();
    super.onPause();
}
}

CommentsDataSource.java

public class CommentsDataSource {
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allColumns = { MySQLiteHelper.COLUMN_ID, MySQLiteHelper.COLUMN_COMMENT };

public CommentsDataSource(Context context) {
    dbHelper = new MySQLiteHelper(context);
}

public void open() throws SQLException {
    database = dbHelper.getWritableDatabase();
}

public void close() {
    dbHelper.close();
}

public Comment createComment(String comment) {
    ContentValues values = new ContentValues();
    values.put(MySQLiteHelper.COLUMN_COMMENT, comment);
    long insertId = database.insert(MySQLiteHelper.TABLE_COMMENTS, null, values);
    Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, allColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null, null, null, null);
    cursor.moveToFirst();
    Comment newComment = cursorToComment(cursor);
    cursor.close();
    return newComment;
}

public void deleteComment(Comment comment) {
    long id = comment.getId();
    System.out.println("Comment deleted with id: " + id);
    database.delete(MySQLiteHelper.TABLE_COMMENTS, MySQLiteHelper.COLUMN_ID + " = " + id, null);
}

public List<Comment> getAllComments() {
    List<Comment> comments = new ArrayList<Comment>();

    Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, allColumns, null, null, null, null, null);

    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
        Comment comment = cursorToComment(cursor);
        comments.add(comment);
        cursor.moveToNext();
    }
    cursor.close();
    return comments;
}

private Comment cursorToComment(Cursor cursor) {
    Comment comment = new Comment();
    comment.setId(cursor.getLong(0));
    comment.setComment(cursor.getString(1));
    return comment;
}
}

Comment.java

public class Comment {
private long id;
private String comment;

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getComment() {
    return comment;
}

public void setComment(String comment) {
    this.comment = comment;
}

@Override
public String toString() {
    return comment;
}
}

Solution

  • ArrayAdapter<Comment> adapter = new ArrayAdapter<Comment>(this, android.R.layout.simple_list_item_1, values);
    

    Here, you are assigning your new ArrayAdapter to a local variable, not your field. Get rid of ArrayAdapter<Comment>, to assign the value to the field.

    private ArrayAdapter<Comment> adapter = (ArrayAdapter<Comment>) getListAdapter();
    

    Here, you are attempting to initialize the field. However, getListAdapter() is guaranteed to return null here, as you have not called setListAdapter(). Replace this with just private ArrayAdapter<Comment> adapter;.