mirror of
https://github.com/AntennaPod/AntennaPod.git
synced 2025-12-01 12:31:45 +00:00
Fix some cases of doing I/O in main thread (#8091)
This commit is contained in:
committed by
GitHub
parent
458d8732c6
commit
2c65402a9b
@ -3,6 +3,7 @@ package de.danoeh.antennapod.ui.screen.playback;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -20,6 +21,10 @@ import de.danoeh.antennapod.event.playback.SpeedChangedEvent;
|
|||||||
import de.danoeh.antennapod.playback.service.PlaybackController;
|
import de.danoeh.antennapod.playback.service.PlaybackController;
|
||||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.ui.view.ItemOffsetDecoration;
|
import de.danoeh.antennapod.ui.view.ItemOffsetDecoration;
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
@ -31,12 +36,14 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class VariableSpeedDialog extends BottomSheetDialogFragment {
|
public class VariableSpeedDialog extends BottomSheetDialogFragment {
|
||||||
|
private static final String TAG = "VariableSpeedDialog";
|
||||||
private SpeedSelectionAdapter adapter;
|
private SpeedSelectionAdapter adapter;
|
||||||
private PlaybackController controller;
|
private PlaybackController controller;
|
||||||
private final List<Float> selectedSpeeds;
|
private final List<Float> selectedSpeeds;
|
||||||
private PlaybackSpeedSeekBar speedSeekBar;
|
private PlaybackSpeedSeekBar speedSeekBar;
|
||||||
private Chip addCurrentSpeedChip;
|
private Chip addCurrentSpeedChip;
|
||||||
private CheckBox skipSilenceCheckbox;
|
private CheckBox skipSilenceCheckbox;
|
||||||
|
private Disposable disposable;
|
||||||
|
|
||||||
public VariableSpeedDialog() {
|
public VariableSpeedDialog() {
|
||||||
DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.US);
|
DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.US);
|
||||||
@ -50,14 +57,12 @@ public class VariableSpeedDialog extends BottomSheetDialogFragment {
|
|||||||
controller = new PlaybackController(getActivity()) {
|
controller = new PlaybackController(getActivity()) {
|
||||||
@Override
|
@Override
|
||||||
public void loadMediaInfo() {
|
public void loadMediaInfo() {
|
||||||
updateSpeed(new SpeedChangedEvent(controller.getCurrentPlaybackSpeedMultiplier()));
|
VariableSpeedDialog.this.loadMediaInfo();
|
||||||
updateSkipSilence(controller.getCurrentPlaybackSkipSilence());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
controller.init();
|
controller.init();
|
||||||
EventBus.getDefault().register(this);
|
EventBus.getDefault().register(this);
|
||||||
updateSpeed(new SpeedChangedEvent(controller.getCurrentPlaybackSpeedMultiplier()));
|
loadMediaInfo();
|
||||||
updateSkipSilence(controller.getCurrentPlaybackSkipSilence());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,6 +71,32 @@ public class VariableSpeedDialog extends BottomSheetDialogFragment {
|
|||||||
controller.release();
|
controller.release();
|
||||||
controller = null;
|
controller = null;
|
||||||
EventBus.getDefault().unregister(this);
|
EventBus.getDefault().unregister(this);
|
||||||
|
if (disposable != null) {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadMediaInfo() {
|
||||||
|
if (disposable != null) {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
|
disposable = Observable.fromCallable(() -> {
|
||||||
|
if (controller == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Make sure the media is loaded in case getCurrentPlaybackSpeedMultiplier has to access it
|
||||||
|
return controller.getMedia();
|
||||||
|
})
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(pair -> {
|
||||||
|
if (controller == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateSpeed(new SpeedChangedEvent(controller.getCurrentPlaybackSpeedMultiplier()));
|
||||||
|
updateSkipSilence(controller.getCurrentPlaybackSkipSilence());
|
||||||
|
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
|||||||
@ -68,7 +68,7 @@ import de.danoeh.antennapod.ui.screen.playback.MediaPlayerErrorDialog;
|
|||||||
import de.danoeh.antennapod.ui.screen.playback.PlaybackControlsDialog;
|
import de.danoeh.antennapod.ui.screen.playback.PlaybackControlsDialog;
|
||||||
import de.danoeh.antennapod.ui.screen.playback.SleepTimerDialog;
|
import de.danoeh.antennapod.ui.screen.playback.SleepTimerDialog;
|
||||||
import de.danoeh.antennapod.ui.screen.playback.VariableSpeedDialog;
|
import de.danoeh.antennapod.ui.screen.playback.VariableSpeedDialog;
|
||||||
import io.reactivex.rxjava3.core.Observable;
|
import io.reactivex.rxjava3.core.Maybe;
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.rxjava3.disposables.Disposable;
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
@ -189,7 +189,6 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar.
|
|||||||
controller = newPlaybackController();
|
controller = newPlaybackController();
|
||||||
controller.init();
|
controller.init();
|
||||||
loadMediaInfo();
|
loadMediaInfo();
|
||||||
onPositionObserverUpdate();
|
|
||||||
EventBus.getDefault().register(this);
|
EventBus.getDefault().register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,24 +265,55 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar.
|
|||||||
|
|
||||||
protected void loadMediaInfo() {
|
protected void loadMediaInfo() {
|
||||||
Log.d(TAG, "loadMediaInfo()");
|
Log.d(TAG, "loadMediaInfo()");
|
||||||
if (controller == null || controller.getMedia() == null) {
|
if (disposable != null) {
|
||||||
return;
|
disposable.dispose();
|
||||||
}
|
|
||||||
if (controller.getStatus() == PlayerStatus.PLAYING && !controller.isPlayingVideoLocally()) {
|
|
||||||
Log.d(TAG, "Closing, no longer video");
|
|
||||||
destroyingDueToReload = true;
|
|
||||||
finish();
|
|
||||||
new MainActivityStarter(this).withOpenPlayer().start();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showTimeLeft = UserPreferences.shouldShowRemainingTime();
|
|
||||||
onPositionObserverUpdate();
|
|
||||||
checkFavorite();
|
|
||||||
Playable media = controller.getMedia();
|
|
||||||
if (media != null) {
|
|
||||||
getSupportActionBar().setSubtitle(media.getEpisodeTitle());
|
|
||||||
getSupportActionBar().setTitle(media.getFeedTitle());
|
|
||||||
}
|
}
|
||||||
|
disposable = Maybe.<Pair<Playable, FeedItem>>create(emitter -> {
|
||||||
|
if (controller == null) {
|
||||||
|
emitter.onComplete();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Playable media = controller.getMedia();
|
||||||
|
if (media == null) {
|
||||||
|
emitter.onComplete();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FeedItem feedItem = getFeedItem(controller.getMedia());
|
||||||
|
if (feedItem != null) {
|
||||||
|
feedItem = DBReader.getFeedItem(feedItem.getId());
|
||||||
|
}
|
||||||
|
emitter.onSuccess(new Pair<>(media, feedItem));
|
||||||
|
})
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
result -> {
|
||||||
|
final Playable media = result.first;
|
||||||
|
final FeedItem item = result.second;
|
||||||
|
if (controller.getStatus() == PlayerStatus.PLAYING
|
||||||
|
&& !controller.isPlayingVideoLocally()) {
|
||||||
|
Log.d(TAG, "Closing, no longer video");
|
||||||
|
destroyingDueToReload = true;
|
||||||
|
finish();
|
||||||
|
new MainActivityStarter(this).withOpenPlayer().start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showTimeLeft = UserPreferences.shouldShowRemainingTime();
|
||||||
|
onPositionObserverUpdate(
|
||||||
|
new PlaybackPositionEvent(controller.getPosition(), controller.getDuration()));
|
||||||
|
|
||||||
|
if (media != null) {
|
||||||
|
getSupportActionBar().setSubtitle(media.getEpisodeTitle());
|
||||||
|
getSupportActionBar().setTitle(media.getFeedTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE);
|
||||||
|
if (isFavorite != isFav) {
|
||||||
|
isFavorite = isFav;
|
||||||
|
invalidateOptionsMenu();
|
||||||
|
}
|
||||||
|
}, error -> Log.e(TAG, Log.getStackTraceString(error))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupView() {
|
protected void setupView() {
|
||||||
@ -532,7 +562,7 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar.
|
|||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
public void onEventMainThread(PlaybackPositionEvent event) {
|
public void onEventMainThread(PlaybackPositionEvent event) {
|
||||||
onPositionObserverUpdate();
|
onPositionObserverUpdate(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
@ -659,24 +689,21 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar.
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onPositionObserverUpdate() {
|
void onPositionObserverUpdate(PlaybackPositionEvent event) {
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
|
TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
|
||||||
int currentPosition = converter.convert(controller.getPosition());
|
int currentPosition = converter.convert(event.getPosition());
|
||||||
int duration = converter.convert(controller.getDuration());
|
int duration = converter.convert(event.getDuration());
|
||||||
int remainingTime = converter.convert(
|
|
||||||
controller.getDuration() - controller.getPosition());
|
|
||||||
Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition));
|
Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition));
|
||||||
if (currentPosition == Playable.INVALID_TIME
|
if (currentPosition == Playable.INVALID_TIME || duration == Playable.INVALID_TIME) {
|
||||||
|| duration == Playable.INVALID_TIME) {
|
|
||||||
Log.w(TAG, "Could not react to position observer update because of invalid time");
|
Log.w(TAG, "Could not react to position observer update because of invalid time");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
viewBinding.positionLabel.setText(Converter.getDurationStringLong(currentPosition));
|
viewBinding.positionLabel.setText(Converter.getDurationStringLong(currentPosition));
|
||||||
if (showTimeLeft) {
|
if (showTimeLeft) {
|
||||||
|
int remainingTime = converter.convert(event.getDuration() - event.getPosition());
|
||||||
viewBinding.durationLabel.setText("-" + Converter.getDurationStringLong(remainingTime));
|
viewBinding.durationLabel.setText("-" + Converter.getDurationStringLong(remainingTime));
|
||||||
} else {
|
} else {
|
||||||
viewBinding.durationLabel.setText(Converter.getDurationStringLong(duration));
|
viewBinding.durationLabel.setText(Converter.getDurationStringLong(duration));
|
||||||
@ -730,27 +757,6 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar.
|
|||||||
setupVideoControlsToggler();
|
setupVideoControlsToggler();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkFavorite() {
|
|
||||||
FeedItem feedItem = getFeedItem(controller.getMedia());
|
|
||||||
if (feedItem == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (disposable != null) {
|
|
||||||
disposable.dispose();
|
|
||||||
}
|
|
||||||
disposable = Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId()))
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
item -> {
|
|
||||||
boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE);
|
|
||||||
if (isFavorite != isFav) {
|
|
||||||
isFavorite = isFav;
|
|
||||||
invalidateOptionsMenu();
|
|
||||||
}
|
|
||||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static FeedItem getFeedItem(@Nullable Playable playable) {
|
private static FeedItem getFeedItem(@Nullable Playable playable) {
|
||||||
if (playable instanceof FeedMedia) {
|
if (playable instanceof FeedMedia) {
|
||||||
|
|||||||
Reference in New Issue
Block a user