FIRST OF ALL, I KNOW WHAT IS AN NULL POINTER EXCEPTION. And no, this thread is not a duplicate So please don't tell me that my object is null, I know it. I just can't understand why, and I think it probably has something to do with the handler thread. I'm a confirmed Android dev, so please just read the problem and stop being insulting with all your "do you know what is a NPE?". Thank you.
I have an Android app in production and some users are experimenting a crash that I just can't reproduce or understand, no matter how hard I try.
To make it simple, I have 2 AutoCompleteTextView
corresponding to the firstname and the lastname of an Author. When you start typing, the EditTexts autocomplete with the existing authors in database.
This is working fine for me and for 95% of my users, but some of them are experimenting a crash, sometimes, when clicking on an item.
Here is the code :
final List<Author> authors = Author.listAll(Author.class);
List<String> authorNames = getAuthorNames(authors, false);
authorLastnameEdittext.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_dropdown_item_1line, authorNames));
authorFirstnameEdittext.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_dropdown_item_1line, authorNames));
AdapterView.OnItemClickListener onExistingAuthorClick = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String text = ((TextView) view).getText().toString();
for (Author a : authors) {
if (!a.toString().equals(text)) {
continue;
}
author = a;
authorLastnameEdittext.setText(author.getLastname());
authorFirstnameEdittext.setText(author.getFirstname());
existingAuthor = true;
}
}
};
The Stacktrace of the NPE that I have in Firebase is :
Exception java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String com.vgm.mylibrary.model.Author.getFirstname()' on a null object reference
com.vgm.mylibrary.dialog.AddBookDialog$7.onItemClick (AddBookDialog.java:292)
android.widget.AutoCompleteTextView.performCompletion (AutoCompleteTextView.java:915)
android.widget.AutoCompleteTextView.access$500 (AutoCompleteTextView.java:91)
android.widget.AutoCompleteTextView$DropDownItemClickListener.onItemClick (AutoCompleteTextView.java:1208)
android.widget.AdapterView.performItemClick (AdapterView.java:334)
android.widget.AbsListView.performItemClick (AbsListView.java:1531)
android.widget.AbsListView$PerformClick.run (AbsListView.java:3667)
android.widget.AbsListView$3.run (AbsListView.java:5590)
android.os.Handler.handleCallback (Handler.java:739)
android.os.Handler.dispatchMessage (Handler.java:95)
android.os.Looper.loop (Looper.java:145)
android.app.ActivityThread.main (ActivityThread.java:5951)
java.lang.reflect.Method.invoke (Method.java)
java.lang.reflect.Method.invoke (Method.java:372)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1388)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1183)
So the NPE happens on this line :
authorFirstnameEdittext.setText(author.getFirstname());
My question is simple : how is that possible ?! The NPE says that at this line, the Author is null. Admit that this is true, the app should have crashed the line before, when doing : authorLastnameEdittext.setText(author.getLastname());
Here is a screenshot of the view to help visualization : Autocomplete screenshot
Thanks !
Edit : I made a modification suggested by pskink, replacing my String ArrayAdapter by an Author ArrayAdapter. So now the code is :
final List<Author> authors = Author.listAll(Author.class);
authorLastnameEdittext.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_dropdown_item_1line, authors));
authorFirstnameEdittext.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_dropdown_item_1line, authors));
AdapterView.OnItemClickListener onExistingAuthorClick = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
author = (Author) parent.getAdapter().getItem(position);
if (author == null) {
return;
}
authorLastnameEdittext.setText(author.getLastname());
authorFirstnameEdittext.setText(author.getFirstname());
existingAuthor = true;
}
};
Please note this does not explain the previous NPE, so if you have ideas you're welcome!