问题
My problem is that my App crashes when the MainActivity
gets resumed.
The error is an IndexOutOfBoundsException
, unfortunately without a specific line. And the error says Index: 0, Size: 0
.
As I know this means that my ArrayList
is null and I call it before I initialize it. But I searched since days after that case. I didn't find anything.
So first here is the Error:
08-28 13:10:24.232 18741-18741/com.test.test.test E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.test.test, PID: 18741
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at com.firebase.ui.common.BaseObservableSnapshotArray.getSnapshot(BaseObservableSnapshotArray.java:70)
at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)
at com.firebase.ui.firestore.FirestoreRecyclerAdapter.getItem(FirestoreRecyclerAdapter.java:83)
at com.firebase.ui.firestore.FirestoreRecyclerAdapter.onBindViewHolder(FirestoreRecyclerAdapter.java:125)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6673)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6714)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5647)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5913)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2232)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1559)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:614)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3529)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1858)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1191)
at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:876)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:895)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1171)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:730)
at android.view.View.layout(View.java:17689)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2346)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2068)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6343)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6274)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
And here is a snippet of my Code:
MainActivity:
public class MainActivity extends AppCompatActivity implements RecyclerItemTouchHelper.RecyclerItemTouchHelperListener, NoteListAdapter.NotesAdapterListener {
private FirebaseAuth mFirebaseAuth;
public FirebaseUser mFirebaseUser;
private FirebaseFirestore db;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager recyclerViewLayoutManager;
public NoteListAdapter adapter;
private List<Note> notesList = new ArrayList<>();
private ListenerRegistration firestoreListener;
private RecyclerItemTouchHelper.RecyclerItemTouchHelperListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getInstance().getCurrentUser();
db = FirebaseFirestore.getInstance();
recyclerView = findViewById(R.id.rvNoteList);
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder().setPersistenceEnabled(true).build();
db.setFirestoreSettings(settings);
Query query = db.collection("users").document(firebase_user_uid).collection("notes");
FirestoreRecyclerOptions<Note> response = new FirestoreRecyclerOptions.Builder<Note>().setQuery(query, Note.class).build();
adapter = new NoteListAdapter(notesList, response, MainActivity.this, MainActivity.this);
recyclerViewLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(recyclerViewLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new CustomRecyclerViewDivider(this, LinearLayoutManager.VERTICAL, 16));
recyclerView.setAdapter(adapter);
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, MainActivity.this);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
firestoreListener = db.collection("users").document(firebase_user_uid).collection("notes")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e != null) {
Log.e("LOL", "Listen failed!", e);
return;
}
notesList.clear();
for (DocumentSnapshot doc : documentSnapshots) {
Note note = doc.toObject(Note.class);
note.setId(doc.getId());
notesList.add(note);
}
}
});
recyclerView.addOnItemTouchListener(new RecyclerViewTouchListener(getApplicationContext(), recyclerView, new RecyclerViewTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
if (notesList != null || notesList.size() <= 0) {
Note note = notesList.get(position);
updateNote(note);
}
}
@Override
public void onLongClick(View view, int position) {
}
}));
}
@Override
public void onStart() {
super.onStart();
if (adapter != null) {
adapter.startListening();
}
}
@Override
public void onStop() {
super.onStop();
if (adapter != null) {
adapter.stopListening();
}
}
@Override
protected void onResume() {
super.onResume();
if (adapter != null) {
adapter.startListening();
}
}}
And here is the NoteListAdapter:
public class NoteListAdapter extends FirestoreRecyclerAdapter<Note, NoteListAdapter.NoteViewHolder> implements Filterable{
private List<Note> notesList;
private List<Note> notesListFiltered;
private NotesAdapterListener listener;
private Context context;
public class NoteViewHolder extends RecyclerView.ViewHolder {
public TextView title, content;
public ImageView bg_note_image;
public RelativeLayout viewBackground, viewForeground;
public NoteViewHolder(View view) {
super(view);
title = view.findViewById(R.id.tvTitle);
content = view.findViewById(R.id.tvContent);
bg_note_image = view.findViewById(R.id.note_image_view);
viewBackground = view.findViewById(R.id.view_background);
viewForeground = view.findViewById(R.id.view_foreground);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onNoteSelected(notesListFiltered.get(getAdapterPosition()));
}
});
}
}
public NoteListAdapter(List<Note> notesList, FirestoreRecyclerOptions<Note> response, Context co, NotesAdapterListener listener) {
super(response);
context = co;
this.listener = listener;
this.notesList = notesList;
this.notesListFiltered = notesList;
}
@Override
protected void onBindViewHolder(NoteViewHolder holder, int position, Note model) {
if (notesListFiltered != null || notesList != null) {
final Note note = notesListFiltered.get(position);
holder.title.setText(note.getTitle());
holder.content.setText(note.getContent());
if (note.getNote_image_url() != null) {
Glide.with(context).load(note.getNote_image_url()).into(holder.bg_note_image);
holder.bg_note_image.setVisibility(View.VISIBLE);
}
}
}
@Override
public NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_view, parent, false);
return new NoteViewHolder(view);
}
@Override
public void onError(FirebaseFirestoreException e) {
Log.e("LOL", e.getMessage());
}
@Override
public int getItemCount() {
return notesListFiltered.size();
}
public void removeItem(int position) {
notesList.remove(position);
// notify the item removed by position
// to perform recycler view delete animations
// NOTE: don't call notifyDataSetChanged()
notifyItemRemoved(position);
}
public void restoreItem(Note item, int position) {
notesList.add(position, item);
// notify item added by position
notifyItemInserted(position);
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
notesListFiltered = notesList;
} else {
List<Note> filteredList = new ArrayList<>();
for (Note row : notesList) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getTitle().toLowerCase().contains(charString.toLowerCase()) || row.getContent().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(row);
}
}
notesListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = notesListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
notesListFiltered = (ArrayList<Note>) filterResults.values;
notifyDataSetChanged();
}
};
}
public interface NotesAdapterListener {
void onNoteSelected(Note note);
}}
And additionally I tried this to find a specific line, but without any success:
@Override
protected void onResume() {
try {
super.onResume();
} catch (Exception e) {
e.printStackTrace();
Log.d("LOL", e.getMessage(), e);
}
}
I really hope anybody has a solution for my problem, because I really don't know how to fix this since one week.
Thanks in advance.
回答1:
Check below code. Hope it will be helpful for you. You need to replace all firebase
firestore
logic to onResume()
method.
public class MainActivity extends AppCompatActivity implements RecyclerItemTouchHelper.RecyclerItemTouchHelperListener, NoteListAdapter.NotesAdapterListener {
private FirebaseAuth mFirebaseAuth;
public FirebaseUser mFirebaseUser;
private FirebaseFirestore db;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager recyclerViewLayoutManager;
public NoteListAdapter adapter;
private List<Note> notesList = new ArrayList<>();
private ListenerRegistration firestoreListener;
private RecyclerItemTouchHelper.RecyclerItemTouchHelperListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rvNoteList);
}
@Override
public void onStart() {
super.onStart();
if (adapter != null) {
adapter.startListening();
}
}
@Override
public void onStop() {
super.onStop();
if (adapter != null) {
adapter.stopListening();
}
}
@Override
protected void onResume() {
super.onResume();
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getInstance().getCurrentUser();
db = FirebaseFirestore.getInstance();
if (adapter != null) {
adapter.startListening();
}
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder().setPersistenceEnabled(true).build();
db.setFirestoreSettings(settings);
Query query = db.collection("users").document(firebase_user_uid).collection("notes");
FirestoreRecyclerOptions<Note> response = new FirestoreRecyclerOptions.Builder<Note>().setQuery(query, Note.class).build();
adapter = new NoteListAdapter(notesList, response, MainActivity.this, MainActivity.this);
recyclerViewLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(recyclerViewLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new CustomRecyclerViewDivider(this, LinearLayoutManager.VERTICAL, 16));
recyclerView.setAdapter(adapter);
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, MainActivity.this);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
firestoreListener = db.collection("users").document(firebase_user_uid).collection("notes")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e != null) {
Log.e("LOL", "Listen failed!", e);
return;
}
notesList.clear();
for (DocumentSnapshot doc : documentSnapshots) {
Note note = doc.toObject(Note.class);
note.setId(doc.getId());
notesList.add(note);
}
}
});
recyclerView.addOnItemTouchListener(new RecyclerViewTouchListener(getApplicationContext(), recyclerView, new RecyclerViewTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
if (notesList != null || notesList.size() <= 0) {
Note note = notesList.get(position);
updateNote(note);
}
}
@Override
public void onLongClick(View view, int position) {
}
}))
}}
回答2:
just change your code to :
notesList.clear();
for (DocumentSnapshot doc : documentSnapshots) {
Note note = doc.toObject(Note.class);
note.setId(doc.getId());
notesList.add(note);
instead use,
firestoreListener = db.collection("users").document(firebase_user_uid).collection("notes")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e != null) {
Log.e("LOL", "Listen failed!", e);
notesList=new ArrayList();
for (DocumentSnapshot doc : documentSnapshots) {
Note note = doc.toObject(Note.class);
note.setId(doc.getId());
notesList.add(note);
}
}
}
});
来源:https://stackoverflow.com/questions/52056917/getting-indexoutofboundsexception-only-when-resume-activity