Fix crash in listview

setData() might get called late after a queue update. If the listview already started to draw, it might trigger a panic if a count mismatch was detected
This commit is contained in:
Adrian Ulrich 2016-11-26 20:51:43 +01:00
parent f749773e35
commit d2559dcaf0

View File

@ -40,6 +40,10 @@ public class ShowQueueAdapter extends BaseAdapter {
* The position we are going to mark as 'active' * The position we are going to mark as 'active'
*/ */
private int mHighlightRow; private int mHighlightRow;
/**
* The cached number of songs
*/
private int mSongCount;
/** /**
* The context to use * The context to use
*/ */
@ -65,6 +69,7 @@ public class ShowQueueAdapter extends BaseAdapter {
public void setData(PlaybackService service, int pos) { public void setData(PlaybackService service, int pos) {
mService = service; mService = service;
mHighlightRow = pos; mHighlightRow = pos;
mSongCount = service.getTimelineLength();
notifyDataSetChanged(); notifyDataSetChanged();
} }
@ -75,7 +80,13 @@ public class ShowQueueAdapter extends BaseAdapter {
*/ */
@Override @Override
public int getCount() { public int getCount() {
return (mService == null ? 0 : mService.getTimelineLength()); // Note: This is only updated by setData() to avoid races with the listView if
// the timeline changes: The listView checks if getCount() changed without
// a call to notifyDataSetChanged() and panics if it detected such a condition.
// This can happen to us as onLayout() might get called before setData() was called during
// a queue update. So we simply cache the count to avoid this crash and won't update it until
// setData() is called by our parent.
return mSongCount;
} }
/** /**
@ -86,7 +97,8 @@ public class ShowQueueAdapter extends BaseAdapter {
*/ */
@Override @Override
public Song getItem(int pos) { public Song getItem(int pos) {
return mService.getSongByQueuePosition(pos); Song item = mService.getSongByQueuePosition(pos);
return (item != null ? item : new Song(-1));
} }
/** /**
@ -125,7 +137,7 @@ public class ShowQueueAdapter extends BaseAdapter {
Song song = getItem(position); Song song = getItem(position);
if (song != null) { // unlikely to fail but seems to happen in the wild. if (song.isFilled()) {
SpannableStringBuilder sb = new SpannableStringBuilder(song.title); SpannableStringBuilder sb = new SpannableStringBuilder(song.title);
sb.append('\n'); sb.append('\n');
sb.append(song.album+", "+song.artist); sb.append(song.album+", "+song.artist);