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 b24648caac
commit 7caf2115a8

View File

@ -40,6 +40,10 @@ public class ShowQueueAdapter extends BaseAdapter {
* The position we are going to mark as 'active'
*/
private int mHighlightRow;
/**
* The cached number of songs
*/
private int mSongCount;
/**
* The context to use
*/
@ -65,6 +69,7 @@ public class ShowQueueAdapter extends BaseAdapter {
public void setData(PlaybackService service, int pos) {
mService = service;
mHighlightRow = pos;
mSongCount = service.getTimelineLength();
notifyDataSetChanged();
}
@ -75,7 +80,13 @@ public class ShowQueueAdapter extends BaseAdapter {
*/
@Override
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
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);
if (song != null) { // unlikely to fail but seems to happen in the wild.
if (song.isFilled()) {
SpannableStringBuilder sb = new SpannableStringBuilder(song.title);
sb.append('\n');
sb.append(song.album+", "+song.artist);