Handle destroied PlaybackService instances.
ShowQueueFragment used to keep a reference to PlaybackService - which may get stale at some point (if the service is re-created), causing the fragment to lose any functionality. This commit gets rid of the long lived reference. (Note that the Adapter still has a semi-long-lived reference. Thats not nice but okay as it only needs to access the SongTimeline)
This commit is contained in:
parent
d2b751e841
commit
5ff7f8eddb
@ -41,7 +41,7 @@ public class ShowQueueFragment extends Fragment
|
|||||||
|
|
||||||
private DragSortListView mListView;
|
private DragSortListView mListView;
|
||||||
private ShowQueueAdapter mListAdapter;
|
private ShowQueueAdapter mListAdapter;
|
||||||
private PlaybackService mService;
|
private boolean mIsPopulated;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
@ -72,15 +72,14 @@ public class ShowQueueFragment extends Fragment
|
|||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
// Get playback service if we can and must
|
// Update the song list if we are not populated and
|
||||||
// This happens eg. during a rotate where the view
|
// have an usable PlaybackService instance.
|
||||||
// was destroyed
|
// This is the case if the Application already fully
|
||||||
if (mService == null && PlaybackService.hasInstance())
|
// started up, but just lost this view (due to rotation).
|
||||||
mService = PlaybackService.get(getActivity());
|
if (!mIsPopulated && PlaybackService.hasInstance()) {
|
||||||
|
|
||||||
if (mService != null)
|
|
||||||
refreshSongQueueList(true);
|
refreshSongQueueList(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private final static int CTX_MENU_PLAY = 100;
|
private final static int CTX_MENU_PLAY = 100;
|
||||||
@ -95,7 +94,7 @@ public class ShowQueueFragment extends Fragment
|
|||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View listView, ContextMenu.ContextMenuInfo absInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View listView, ContextMenu.ContextMenuInfo absInfo) {
|
||||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)absInfo;
|
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)absInfo;
|
||||||
Song song = mService.getSongByQueuePosition(info.position);
|
Song song = playbackService().getSongByQueuePosition(info.position);
|
||||||
|
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.putExtra("id", song.id);
|
intent.putExtra("id", song.id);
|
||||||
@ -121,19 +120,20 @@ public class ShowQueueFragment extends Fragment
|
|||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
int pos = intent.getIntExtra("position", -1);
|
int pos = intent.getIntExtra("position", -1);
|
||||||
|
|
||||||
Song song = mService.getSongByQueuePosition(pos);
|
PlaybackService service = playbackService();
|
||||||
|
Song song = service.getSongByQueuePosition(pos);
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case CTX_MENU_PLAY:
|
case CTX_MENU_PLAY:
|
||||||
onItemClick(null, null, pos, -1);
|
onItemClick(null, null, pos, -1);
|
||||||
break;
|
break;
|
||||||
case CTX_MENU_ENQUEUE_ALBUM:
|
case CTX_MENU_ENQUEUE_ALBUM:
|
||||||
mService.enqueueFromSong(song, MediaUtils.TYPE_ALBUM);
|
service.enqueueFromSong(song, MediaUtils.TYPE_ALBUM);
|
||||||
break;
|
break;
|
||||||
case CTX_MENU_ENQUEUE_ARTIST:
|
case CTX_MENU_ENQUEUE_ARTIST:
|
||||||
mService.enqueueFromSong(song, MediaUtils.TYPE_ARTIST);
|
service.enqueueFromSong(song, MediaUtils.TYPE_ARTIST);
|
||||||
break;
|
break;
|
||||||
case CTX_MENU_ENQUEUE_GENRE:
|
case CTX_MENU_ENQUEUE_GENRE:
|
||||||
mService.enqueueFromSong(song, MediaUtils.TYPE_GENRE);
|
service.enqueueFromSong(song, MediaUtils.TYPE_GENRE);
|
||||||
break;
|
break;
|
||||||
case CTX_MENU_REMOVE:
|
case CTX_MENU_REMOVE:
|
||||||
remove(pos);
|
remove(pos);
|
||||||
@ -154,7 +154,7 @@ public class ShowQueueFragment extends Fragment
|
|||||||
@Override
|
@Override
|
||||||
public void drop(int from, int to) {
|
public void drop(int from, int to) {
|
||||||
if (from != to) {
|
if (from != to) {
|
||||||
mService.moveSongPosition(from, to);
|
playbackService().moveSongPosition(from, to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ public class ShowQueueFragment extends Fragment
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void remove(int which) {
|
public void remove(int which) {
|
||||||
mService.removeSongPosition(which);
|
playbackService().removeSongPosition(which);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,7 +172,7 @@ public class ShowQueueFragment extends Fragment
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
mService.jumpToQueuePosition(position);
|
playbackService().jumpToQueuePosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,15 +180,17 @@ public class ShowQueueFragment extends Fragment
|
|||||||
* @param scroll enable or disable jumping to the currently playing item
|
* @param scroll enable or disable jumping to the currently playing item
|
||||||
*/
|
*/
|
||||||
private void refreshSongQueueList(final boolean scroll) {
|
private void refreshSongQueueList(final boolean scroll) {
|
||||||
|
final PlaybackService service = playbackService();
|
||||||
|
final int pos = service.getTimelinePosition();
|
||||||
getActivity().runOnUiThread(new Runnable(){
|
getActivity().runOnUiThread(new Runnable(){
|
||||||
public void run() {
|
public void run() {
|
||||||
int pos = mService.getTimelinePosition();
|
mListAdapter.setData(service, pos);
|
||||||
mListAdapter.setData(mService, pos);
|
|
||||||
|
|
||||||
if(scroll)
|
if(scroll)
|
||||||
scrollToCurrentSong(pos);
|
scrollToCurrentSong(pos);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
mIsPopulated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,15 +208,26 @@ public class ShowQueueFragment extends Fragment
|
|||||||
mListView.setSelectionFromTop(currentSongPosition, 0); /* scroll to currently playing song */
|
mListView.setSelectionFromTop(currentSongPosition, 0); /* scroll to currently playing song */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut function to get the current playback service
|
||||||
|
* using our parent activity as context
|
||||||
|
*/
|
||||||
|
private PlaybackService playbackService() {
|
||||||
|
return PlaybackService.get(getActivity());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after a song has been set.
|
* Called after a song has been set.
|
||||||
* We are only interested in this call if mService is null
|
*
|
||||||
* as this signals that the playback service just became ready
|
* We are generally not interested in such events as we do not display
|
||||||
* (and wasn't during onResume())
|
* any playback state - only the queue (which has its changes announced
|
||||||
|
* using `onTimelineChanged()'.
|
||||||
|
* However: We are still interested in `setSong()' if we are unpopulated:
|
||||||
|
* Such an event will then indicate that the PlaybackService just finished
|
||||||
|
* its startup and is ready to be queried.
|
||||||
*/
|
*/
|
||||||
public void setSong(long uptime, Song song) {
|
public void setSong(long uptime, Song song) {
|
||||||
if (mService == null) {
|
if (!mIsPopulated) {
|
||||||
mService = PlaybackService.get(getActivity());
|
|
||||||
onTimelineChanged();
|
onTimelineChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,9 +236,10 @@ public class ShowQueueFragment extends Fragment
|
|||||||
* Called after the timeline changed
|
* Called after the timeline changed
|
||||||
*/
|
*/
|
||||||
public void onTimelineChanged() {
|
public void onTimelineChanged() {
|
||||||
if (mService != null)
|
if (PlaybackService.hasInstance()) {
|
||||||
refreshSongQueueList(false);
|
refreshSongQueueList(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Unused Callbacks of TimelineCallback
|
// Unused Callbacks of TimelineCallback
|
||||||
public void onPositionInfoChanged() {
|
public void onPositionInfoChanged() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user