Reorganize downloads fragments lifecycle
Unregistering from the EventDistributor on stop will prevent downloads from updating when an episode finishes playing while the screen was off (#2747), so this registers/unregisters on view create/destroy. Disposing of the request to load items on stop could potentially cause the same issue. Since we're disposing of this request on destroy, there's no need to keep checking and disposing of it in the several lifecycle methods. There's no need to call `onFragmentLoaded()` on attach, since this is the first lifecycle method to be called [[1]], meaning the items will always be null by the time this method is called. Finally, since `loadItems` depends on the view being created, it is now only called on view create to avoid having to store state in the class about whether the view has been created, taking advantage of the native fragment lifecycle. [1]: https://developer.android.com/guide/components/fragments Closes: #2747
This commit is contained in:
parent
a556183d60
commit
486ceed0ef
|
@ -1,6 +1,5 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ListFragment;
|
||||
|
@ -11,6 +10,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
|
@ -42,24 +42,27 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||
EventDistributor.DOWNLOADLOG_UPDATE |
|
||||
EventDistributor.UNREAD_ITEMS_UPDATE;
|
||||
|
||||
private List<FeedItem> items;
|
||||
private List<FeedItem> items = new ArrayList<>();
|
||||
private DownloadedEpisodesListAdapter listAdapter;
|
||||
|
||||
private boolean viewCreated = false;
|
||||
|
||||
private Disposable disposable;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
loadItems();
|
||||
addVerticalPadding();
|
||||
addEmptyView();
|
||||
|
||||
listAdapter = new DownloadedEpisodesListAdapter(getActivity(), itemAccess);
|
||||
setListAdapter(listAdapter);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
EventDistributor.getInstance().register(contentUpdate);
|
||||
loadItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,41 +75,28 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
super.onListItemClick(l, v, position, id);
|
||||
position -= l.getHeaderViewsCount();
|
||||
long[] ids = FeedItemUtil.getIds(items);
|
||||
((MainActivity) requireActivity()).loadChildFragment(ItemFragment.newInstance(ids, position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
listAdapter = null;
|
||||
viewCreated = false;
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.downloads_completed, menu);
|
||||
menu.findItem(R.id.episode_actions).setVisible(items.size() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (viewCreated && items != null) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
addVerticalPadding();
|
||||
addEmptyView();
|
||||
|
||||
viewCreated = true;
|
||||
if (items != null && getActivity() != null) {
|
||||
onFragmentLoaded();
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.episode_actions) {
|
||||
((MainActivity) requireActivity())
|
||||
.loadChildFragment(EpisodesApplyActionFragment.newInstance(items, ACTION_DELETE | ACTION_ADD_TO_QUEUE));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addEmptyView() {
|
||||
|
@ -123,55 +113,15 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||
lv.setPadding(0, vertPadding, 0, vertPadding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
super.onListItemClick(l, v, position, id);
|
||||
position -= l.getHeaderViewsCount();
|
||||
long[] ids = FeedItemUtil.getIds(items);
|
||||
((MainActivity) requireActivity()).loadChildFragment(ItemFragment.newInstance(ids, position));
|
||||
}
|
||||
|
||||
private void onFragmentLoaded() {
|
||||
if (listAdapter == null) {
|
||||
listAdapter = new DownloadedEpisodesListAdapter(getActivity(), itemAccess);
|
||||
setListAdapter(listAdapter);
|
||||
}
|
||||
setListShown(true);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
requireActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
if (!isAdded()) {
|
||||
return;
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
if (items != null) {
|
||||
inflater.inflate(R.menu.downloads_completed, menu);
|
||||
menu.findItem(R.id.episode_actions).setVisible(items.size() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.episode_actions) {
|
||||
((MainActivity) requireActivity())
|
||||
.loadChildFragment(EpisodesApplyActionFragment.newInstance(items, ACTION_DELETE | ACTION_ADD_TO_QUEUE));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private final DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() {
|
||||
@Override
|
||||
public int getCount() {
|
||||
return (items != null) ? items.size() : 0;
|
||||
return items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedItem getItem(int position) {
|
||||
if (items != null && 0 <= position && position < items.size()) {
|
||||
if (0 <= position && position < items.size()) {
|
||||
return items.get(position);
|
||||
} else {
|
||||
return null;
|
||||
|
@ -197,18 +147,18 @@ public class CompletedDownloadsFragment extends ListFragment {
|
|||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
if (items == null && viewCreated) {
|
||||
setListShown(false);
|
||||
}
|
||||
disposable = Observable.fromCallable(DBReader::getDownloadedItems)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
items = result;
|
||||
if (viewCreated && getActivity() != null) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
onItemsLoaded();
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
||||
private void onItemsLoaded() {
|
||||
setListShown(true);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
requireActivity().invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ import android.view.View;
|
|||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
|
@ -21,8 +25,6 @@ import de.danoeh.antennapod.core.storage.DBReader;
|
|||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
/**
|
||||
* Displays all running downloads and provides actions to cancel them
|
||||
|
@ -32,7 +34,7 @@ public class RunningDownloadsFragment extends ListFragment {
|
|||
private static final String TAG = "RunningDownloadsFrag";
|
||||
|
||||
private DownloadlistAdapter adapter;
|
||||
private List<Downloader> downloaderList;
|
||||
private List<Downloader> downloaderList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
|
@ -70,7 +72,6 @@ public class RunningDownloadsFragment extends ListFragment {
|
|||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
setListAdapter(null);
|
||||
adapter = null;
|
||||
}
|
||||
|
||||
@Subscribe(sticky = true)
|
||||
|
@ -78,21 +79,18 @@ public class RunningDownloadsFragment extends ListFragment {
|
|||
Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]");
|
||||
DownloaderUpdate update = event.update;
|
||||
downloaderList = update.downloaders;
|
||||
if (adapter != null) {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
private final DownloadlistAdapter.ItemAccess itemAccess = new DownloadlistAdapter.ItemAccess() {
|
||||
@Override
|
||||
public int getCount() {
|
||||
return (downloaderList != null) ? downloaderList.size() : 0;
|
||||
return downloaderList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Downloader getItem(int position) {
|
||||
if (downloaderList != null && 0 <= position && position < downloaderList.size()) {
|
||||
if (0 <= position && position < downloaderList.size()) {
|
||||
return downloaderList.get(position);
|
||||
} else {
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue