Skip to content

Commit 944e295

Browse files
committed
Use Optional for simpler code
1 parent 28109fe commit 944e295

1 file changed

Lines changed: 77 additions & 83 deletions

File tree

app/src/main/java/org/schabi/newpipe/RouterActivity.java

Lines changed: 77 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,16 @@
9191
import java.util.ArrayList;
9292
import java.util.Arrays;
9393
import java.util.List;
94+
import java.util.Optional;
95+
import java.util.function.Consumer;
9496

9597
import icepick.Icepick;
9698
import icepick.State;
9799
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
98100
import io.reactivex.rxjava3.core.Observable;
99101
import io.reactivex.rxjava3.core.Single;
100-
import io.reactivex.rxjava3.core.SingleTransformer;
101102
import io.reactivex.rxjava3.disposables.CompositeDisposable;
102103
import io.reactivex.rxjava3.disposables.Disposable;
103-
import io.reactivex.rxjava3.functions.Consumer;
104104
import io.reactivex.rxjava3.schedulers.Schedulers;
105105

106106
/**
@@ -702,7 +702,7 @@ private boolean canHandleChoiceLikeShowInfo(final String selectedChoiceKey) {
702702
}
703703

704704
public static class PersistentFragment extends Fragment {
705-
private WeakReference<AppCompatActivity> context;
705+
private WeakReference<AppCompatActivity> weakContext;
706706
private final CompositeDisposable disposables = new CompositeDisposable();
707707
private int running = 0;
708708

@@ -711,21 +711,23 @@ private synchronized void inFlight(final boolean started) {
711711
running++;
712712
} else {
713713
running--;
714-
if (running <= 0 && getActivityContext() != null) {
715-
getActivityContext().getSupportFragmentManager()
716-
.beginTransaction().remove(this).commit();
714+
if (running <= 0) {
715+
getActivityContext().ifPresent(context -> context.getSupportFragmentManager()
716+
.beginTransaction().remove(this).commit());
717717
}
718718
}
719719
}
720720

721-
public interface ResultRunnable {
722-
void run(AppCompatActivity context);
723-
}
724-
725721
@Override
726722
public void onAttach(@NonNull final Context activityContext) {
727723
super.onAttach(activityContext);
728-
context = new WeakReference<>((AppCompatActivity) activityContext);
724+
weakContext = new WeakReference<>((AppCompatActivity) activityContext);
725+
}
726+
727+
@Override
728+
public void onDetach() {
729+
super.onDetach();
730+
weakContext = null;
729731
}
730732

731733
@SuppressWarnings("deprecation")
@@ -741,73 +743,70 @@ public void onDestroy() {
741743
disposables.clear();
742744
}
743745

744-
private AppCompatActivity getActivityContext() {
745-
return context == null ? null : context.get();
746-
}
747-
748-
private boolean activityGone() {
749-
return getActivityContext() == null || getActivityContext().isFinishing();
746+
/**
747+
* @return the activity context, if there is one and the activity is not finishing
748+
*/
749+
private Optional<AppCompatActivity> getActivityContext() {
750+
return Optional.ofNullable(weakContext)
751+
.flatMap(context -> Optional.ofNullable(context.get()))
752+
.filter(context -> !context.isFinishing());
750753
}
751754

752755
// guard against IllegalStateException in calling DialogFragment.show() whilst in background
753756
// (which could happen, say, when the user pressed the home button while waiting for
754757
// the network request to return) when it internally calls FragmentTransaction.commit()
755758
// after the FragmentManager has saved its states (isStateSaved() == true)
756759
// (ref: https://stackoverflow.com/a/39813506)
757-
private void runOnVisible(final ResultRunnable runnable) {
758-
if (activityGone()) {
759-
inFlight(false);
760-
return;
761-
}
762-
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
763-
getActivityContext().runOnUiThread(() -> {
764-
runnable.run(getActivityContext());
765-
inFlight(false);
766-
});
767-
} else {
768-
getLifecycle().addObserver(new DefaultLifecycleObserver() {
769-
@Override
770-
public void onResume(@NonNull final LifecycleOwner owner) {
771-
getLifecycle().removeObserver(this);
772-
if (activityGone()) {
773-
inFlight(false);
774-
return;
760+
private void runOnVisible(final Consumer<AppCompatActivity> runnable) {
761+
getActivityContext().ifPresentOrElse(context -> {
762+
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
763+
context.runOnUiThread(() -> {
764+
runnable.accept(context);
765+
inFlight(false);
766+
});
767+
} else {
768+
getLifecycle().addObserver(new DefaultLifecycleObserver() {
769+
@Override
770+
public void onResume(@NonNull final LifecycleOwner owner) {
771+
getLifecycle().removeObserver(this);
772+
getActivityContext().ifPresentOrElse(context ->
773+
context.runOnUiThread(() -> {
774+
runnable.accept(context);
775+
inFlight(false);
776+
}),
777+
() -> inFlight(false)
778+
);
775779
}
776-
getActivityContext().runOnUiThread(() -> {
777-
runnable.run(getActivityContext());
778-
inFlight(false);
779-
});
780+
});
781+
// this trick doesn't seem to work on Android 10+ (API 29)
782+
// which places restrictions on starting activities from the background
783+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
784+
&& !context.isChangingConfigurations()) {
785+
// try to bring the activity back to front if minimised
786+
final Intent i = new Intent(context, RouterActivity.class);
787+
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
788+
startActivity(i);
780789
}
781-
});
782-
// this trick doesn't seem to work on Android 10+ (API 29)
783-
// which places restrictions on starting activities from the background
784-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
785-
&& !getActivityContext().isChangingConfigurations()) {
786-
// try to bring the activity back to front if minimised
787-
final Intent i = new Intent(getActivityContext(), RouterActivity.class);
788-
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
789-
startActivity(i);
790790
}
791-
}
791+
792+
}, () -> {
793+
// this branch is executed if there is no activity context
794+
inFlight(false);
795+
});
792796
}
793797

794-
<T> SingleTransformer<T, T> pleaseWait() {
795-
return single -> single
796-
// 'abuse' ambWith() here to cancel the toast for us when the wait is over
797-
.ambWith(Single.create(emitter -> {
798-
if (!activityGone()) {
799-
getActivityContext().runOnUiThread(() -> {
800-
// Getting the stream info usually takes a moment
801-
// Notifying the user here to ensure that no confusion arises
802-
final Toast t = Toast.makeText(
803-
getActivityContext().getApplicationContext(),
804-
getString(R.string.processing_may_take_a_moment),
805-
Toast.LENGTH_LONG);
806-
t.show();
807-
emitter.setCancellable(t::cancel);
808-
});
809-
}
810-
}));
798+
<T> Single<T> pleaseWait(final Single<T> single) {
799+
// 'abuse' ambWith() here to cancel the toast for us when the wait is over
800+
return single.ambWith(Single.create(emitter -> getActivityContext().ifPresent(context ->
801+
context.runOnUiThread(() -> {
802+
// Getting the stream info usually takes a moment
803+
// Notifying the user here to ensure that no confusion arises
804+
final Toast toast = Toast.makeText(context,
805+
getString(R.string.processing_may_take_a_moment),
806+
Toast.LENGTH_LONG);
807+
toast.show();
808+
emitter.setCancellable(toast::cancel);
809+
}))));
811810
}
812811

813812
@SuppressLint("CheckResult")
@@ -816,7 +815,7 @@ private void openDownloadDialog(final int currentServiceId, final String current
816815
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
817816
.subscribeOn(Schedulers.io())
818817
.observeOn(AndroidSchedulers.mainThread())
819-
.compose(pleaseWait())
818+
.compose(this::pleaseWait)
820819
.subscribe(result ->
821820
runOnVisible(ctx -> {
822821
final FragmentManager fm = ctx.getSupportFragmentManager();
@@ -833,23 +832,18 @@ private void openAddToPlaylistDialog(final int currentServiceId, final String cu
833832
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false)
834833
.subscribeOn(Schedulers.io())
835834
.observeOn(AndroidSchedulers.mainThread())
836-
.compose(pleaseWait())
835+
.compose(this::pleaseWait)
837836
.subscribe(
838-
info -> {
839-
if (!activityGone()) {
840-
PlaylistDialog.createCorrespondingDialog(
841-
getActivityContext(),
842-
List.of(new StreamEntity(info)),
843-
playlistDialog ->
844-
runOnVisible(ctx -> {
845-
// dismiss listener to be handled by FragmentManager
846-
final FragmentManager fm =
847-
ctx.getSupportFragmentManager();
848-
playlistDialog.show(fm, "addToPlaylistDialog");
849-
})
850-
);
851-
}
852-
},
837+
info -> getActivityContext().ifPresent(context ->
838+
PlaylistDialog.createCorrespondingDialog(context,
839+
List.of(new StreamEntity(info)),
840+
playlistDialog -> runOnVisible(ctx -> {
841+
// dismiss listener to be handled by FragmentManager
842+
final FragmentManager fm =
843+
ctx.getSupportFragmentManager();
844+
playlistDialog.show(fm, "addToPlaylistDialog");
845+
})
846+
)),
853847
throwable -> runOnVisible(ctx -> handleError(ctx, new ErrorInfo(
854848
throwable,
855849
UserAction.REQUESTED_STREAM,

0 commit comments

Comments
 (0)