Merge pull request #1292 from mfietz/issue/1290-NPE
NPE: ItemFragment Loader.loadInBackground
This commit is contained in:
commit
ebd6686ca6
@ -11,8 +11,6 @@ import android.os.Bundle;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.LoaderManager;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
import android.support.v7.widget.PopupMenu;
|
import android.support.v7.widget.PopupMenu;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
@ -42,12 +40,11 @@ import java.util.List;
|
|||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
import de.danoeh.antennapod.activity.MainActivity;
|
||||||
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
|
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
|
||||||
import de.danoeh.antennapod.core.asynctask.DBTaskLoader;
|
|
||||||
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
|
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
|
||||||
|
import de.danoeh.antennapod.core.event.QueueEvent;
|
||||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.event.QueueEvent;
|
|
||||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||||
@ -63,11 +60,15 @@ import de.danoeh.antennapod.core.util.ShareUtils;
|
|||||||
import de.danoeh.antennapod.core.util.playback.Timeline;
|
import de.danoeh.antennapod.core.util.playback.Timeline;
|
||||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||||
import de.greenrobot.event.EventBus;
|
import de.greenrobot.event.EventBus;
|
||||||
|
import rx.Observable;
|
||||||
|
import rx.Subscription;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays information about a FeedItem and actions.
|
* Displays information about a FeedItem and actions.
|
||||||
*/
|
*/
|
||||||
public class ItemFragment extends Fragment implements LoaderManager.LoaderCallbacks<Pair<FeedItem, LongList>> {
|
public class ItemFragment extends Fragment {
|
||||||
|
|
||||||
private static final String TAG = "ItemFragment";
|
private static final String TAG = "ItemFragment";
|
||||||
|
|
||||||
@ -113,6 +114,8 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
|
|||||||
private ImageButton butMore;
|
private ImageButton butMore;
|
||||||
private PopupMenu popupMenu;
|
private PopupMenu popupMenu;
|
||||||
|
|
||||||
|
private Subscription subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL that was selected via long-press.
|
* URL that was selected via long-press.
|
||||||
*/
|
*/
|
||||||
@ -127,55 +130,6 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
|
|||||||
itemID = getArguments().getLong(ARG_FEEDITEM, -1);
|
itemID = getArguments().getLong(ARG_FEEDITEM, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
getLoaderManager().initLoader(0, null, this);
|
|
||||||
Toolbar toolbar = ((MainActivity) getActivity()).getToolbar();
|
|
||||||
toolbar.addView(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
EventDistributor.getInstance().register(contentUpdate);
|
|
||||||
EventBus.getDefault().register(this);
|
|
||||||
if (downloadObserver != null) {
|
|
||||||
downloadObserver.setActivity(getActivity());
|
|
||||||
downloadObserver.onResume();
|
|
||||||
}
|
|
||||||
if (itemsLoaded) {
|
|
||||||
onFragmentLoaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
EventDistributor.getInstance().unregister(contentUpdate);
|
|
||||||
EventBus.getDefault().unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetViewState() {
|
|
||||||
if (downloadObserver != null) {
|
|
||||||
downloadObserver.onPause();
|
|
||||||
}
|
|
||||||
Toolbar toolbar = ((MainActivity) getActivity()).getToolbar();
|
|
||||||
toolbar.removeView(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyView() {
|
|
||||||
super.onDestroyView();
|
|
||||||
resetViewState();
|
|
||||||
if (webvDescription != null && root != null) {
|
|
||||||
root.removeView(webvDescription);
|
|
||||||
webvDescription.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
@ -195,19 +149,18 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
|
|||||||
webvDescription = (WebView) layout.findViewById(R.id.webvDescription);
|
webvDescription = (WebView) layout.findViewById(R.id.webvDescription);
|
||||||
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
||||||
if (Build.VERSION.SDK_INT >= 11
|
if (Build.VERSION.SDK_INT >= 11
|
||||||
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||||
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
}
|
}
|
||||||
webvDescription.setBackgroundColor(getResources().getColor(
|
webvDescription.setBackgroundColor(getResources().getColor(
|
||||||
R.color.black));
|
R.color.black));
|
||||||
}
|
}
|
||||||
webvDescription.getSettings().setUseWideViewPort(false);
|
webvDescription.getSettings().setUseWideViewPort(false);
|
||||||
webvDescription.getSettings().setLayoutAlgorithm(
|
webvDescription.getSettings().setLayoutAlgorithm(
|
||||||
WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
|
WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
|
||||||
webvDescription.getSettings().setLoadWithOverviewMode(true);
|
webvDescription.getSettings().setLoadWithOverviewMode(true);
|
||||||
webvDescription.setOnLongClickListener(webViewLongClickListener);
|
webvDescription.setOnLongClickListener(webViewLongClickListener);
|
||||||
webvDescription.setWebViewClient(new WebViewClient() {
|
webvDescription.setWebViewClient(new WebViewClient() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||||
@ -243,74 +196,111 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
|
|||||||
((MainActivity) getActivity()).dismissChildFragment();
|
((MainActivity) getActivity()).dismissChildFragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
butAction2.setOnClickListener(new View.OnClickListener()
|
butAction2.setOnClickListener(v -> {
|
||||||
|
if (item == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
if (item.hasMedia()) {
|
||||||
@Override
|
FeedMedia media = item.getMedia();
|
||||||
public void onClick(View v) {
|
if (!media.isDownloaded()) {
|
||||||
if (item == null) {
|
DBTasks.playMedia(getActivity(), media, true, true, true);
|
||||||
return;
|
((MainActivity) getActivity()).dismissChildFragment();
|
||||||
}
|
} else {
|
||||||
|
DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId());
|
||||||
if (item.hasMedia()) {
|
}
|
||||||
FeedMedia media = item.getMedia();
|
} else if (item.getLink() != null) {
|
||||||
if (!media.isDownloaded()) {
|
Uri uri = Uri.parse(item.getLink());
|
||||||
DBTasks.playMedia(getActivity(), media, true, true, true);
|
getActivity().startActivity(new Intent(Intent.ACTION_VIEW, uri));
|
||||||
((MainActivity) getActivity()).dismissChildFragment();
|
}
|
||||||
} else {
|
}
|
||||||
DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId());
|
|
||||||
}
|
|
||||||
} else if (item.getLink() != null) {
|
|
||||||
Uri uri = Uri.parse(item.getLink());
|
|
||||||
getActivity().startActivity(new Intent(Intent.ACTION_VIEW, uri));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
butMore.setOnClickListener(new View.OnClickListener() {
|
butMore.setOnClickListener(v -> {
|
||||||
@Override
|
if (item == null) {
|
||||||
public void onClick(View v) {
|
return;
|
||||||
if (item == null) {
|
}
|
||||||
return;
|
popupMenu.getMenu().clear();
|
||||||
}
|
popupMenu.inflate(R.menu.feeditem_options);
|
||||||
popupMenu.getMenu().clear();
|
if (item.hasMedia()) {
|
||||||
popupMenu.inflate(R.menu.feeditem_options);
|
FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue);
|
||||||
if (item.hasMedia()) {
|
} else {
|
||||||
FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue);
|
// these are already available via button1 and button2
|
||||||
} else {
|
FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue,
|
||||||
// these are already available via button1 and button2
|
R.id.mark_read_item, R.id.visit_website_item);
|
||||||
FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue,
|
}
|
||||||
R.id.mark_read_item, R.id.visit_website_item);
|
popupMenu.show();
|
||||||
}
|
}
|
||||||
popupMenu.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
popupMenu.setOnMenuItemClickListener(menuItem -> {
|
||||||
@Override
|
|
||||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return FeedItemMenuHandler.onMenuItemClicked(getActivity(), menuItem.getItemId(), item);
|
return FeedItemMenuHandler.onMenuItemClicked(getActivity(), menuItem.getItemId(), item);
|
||||||
} catch (DownloadRequestException e) {
|
} catch (DownloadRequestException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
Toolbar toolbar = ((MainActivity) getActivity()).getToolbar();
|
||||||
|
toolbar.addView(header);
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
EventDistributor.getInstance().register(contentUpdate);
|
||||||
|
EventBus.getDefault().register(this);
|
||||||
|
if (downloadObserver != null) {
|
||||||
|
downloadObserver.setActivity(getActivity());
|
||||||
|
downloadObserver.onResume();
|
||||||
|
}
|
||||||
|
if(itemsLoaded) {
|
||||||
|
updateAppearance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
EventDistributor.getInstance().unregister(contentUpdate);
|
||||||
|
EventBus.getDefault().unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
resetViewState();
|
||||||
|
if(subscription != null) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
if (webvDescription != null && root != null) {
|
||||||
|
root.removeView(webvDescription);
|
||||||
|
webvDescription.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetViewState() {
|
||||||
|
if (downloadObserver != null) {
|
||||||
|
downloadObserver.onPause();
|
||||||
|
}
|
||||||
|
Toolbar toolbar = ((MainActivity) getActivity()).getToolbar();
|
||||||
|
toolbar.removeView(header);
|
||||||
|
}
|
||||||
|
|
||||||
private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() {
|
private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() {
|
||||||
@Override
|
@Override
|
||||||
public void setItemVisibility(int id, boolean visible) {
|
public void setItemVisibility(int id, boolean visible) {
|
||||||
@ -409,11 +399,6 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEvent(QueueEvent event) {
|
|
||||||
Log.d(TAG, "onEvent(" + event + ")");
|
|
||||||
getLoaderManager().restartLoader(0, null, ItemFragment.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private View.OnLongClickListener webViewLongClickListener = new View.OnLongClickListener() {
|
private View.OnLongClickListener webViewLongClickListener = new View.OnLongClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -491,46 +476,18 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void onEventMainThread(QueueEvent event) {
|
||||||
public Loader<Pair<FeedItem,LongList>> onCreateLoader(int id, Bundle args) {
|
if(event.contains(itemID)) {
|
||||||
return new DBTaskLoader<Pair<FeedItem,LongList>>(getActivity()) {
|
updateAppearance();
|
||||||
@Override
|
|
||||||
public Pair<FeedItem,LongList> loadInBackground() {
|
|
||||||
FeedItem data1 = DBReader.getFeedItem(itemID);
|
|
||||||
if (data1 != null) {
|
|
||||||
Timeline t = new Timeline(getActivity(), data1);
|
|
||||||
webviewData = t.processShownotes(false);
|
|
||||||
}
|
|
||||||
LongList data2 = DBReader.getQueueIDList();
|
|
||||||
return Pair.create(data1, data2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadFinished(Loader<Pair<FeedItem,LongList>> loader, Pair<FeedItem,LongList> data) {
|
|
||||||
|
|
||||||
if (data != null) {
|
|
||||||
item = data.first;
|
|
||||||
queue = data.second;
|
|
||||||
if (!itemsLoaded) {
|
|
||||||
itemsLoaded = true;
|
|
||||||
onFragmentLoaded();
|
|
||||||
} else {
|
|
||||||
updateAppearance();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoaderReset(Loader<Pair<FeedItem,LongList>> loader) {
|
|
||||||
}
|
|
||||||
|
|
||||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||||
if ((arg & EVENTS) != 0) {
|
if ((arg & EVENTS) != 0) {
|
||||||
getLoaderManager().restartLoader(0, null, ItemFragment.this);
|
updateAppearance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -545,4 +502,36 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private void load() {
|
||||||
|
if(subscription != null) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
subscription = Observable.defer(() -> Observable.just(loadInBackground()))
|
||||||
|
.subscribeOn(Schedulers.newThread())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(result -> {
|
||||||
|
item = result.first;
|
||||||
|
queue = result.second;
|
||||||
|
if (!itemsLoaded) {
|
||||||
|
itemsLoaded = true;
|
||||||
|
onFragmentLoaded();
|
||||||
|
} else {
|
||||||
|
updateAppearance();
|
||||||
|
}
|
||||||
|
}, error -> {
|
||||||
|
Log.e(TAG, Log.getStackTraceString(error));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<FeedItem,LongList> loadInBackground() {
|
||||||
|
FeedItem data1 = DBReader.getFeedItem(itemID);
|
||||||
|
if (data1 != null) {
|
||||||
|
Timeline t = new Timeline(getActivity(), data1);
|
||||||
|
webviewData = t.processShownotes(false);
|
||||||
|
}
|
||||||
|
LongList data2 = DBReader.getQueueIDList();
|
||||||
|
return Pair.create(data1, data2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,18 @@ public class QueueEvent {
|
|||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean contains(long id) {
|
||||||
|
if(item != null) {
|
||||||
|
return item.getId() == id;
|
||||||
|
}
|
||||||
|
for(FeedItem item : items) {
|
||||||
|
if(item.getId() == id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user