1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-06-27 23:53:19 +00:00

Use Optional for simpler code

This commit is contained in:
Stypox 2023-01-11 15:08:10 +01:00
parent 28109fef38
commit 944e295ae7
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23

View File

@ -91,16 +91,16 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import icepick.Icepick; import icepick.Icepick;
import icepick.State; import icepick.State;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.core.SingleTransformer;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers; import io.reactivex.rxjava3.schedulers.Schedulers;
/** /**
@ -702,7 +702,7 @@ public class RouterActivity extends AppCompatActivity {
} }
public static class PersistentFragment extends Fragment { public static class PersistentFragment extends Fragment {
private WeakReference<AppCompatActivity> context; private WeakReference<AppCompatActivity> weakContext;
private final CompositeDisposable disposables = new CompositeDisposable(); private final CompositeDisposable disposables = new CompositeDisposable();
private int running = 0; private int running = 0;
@ -711,21 +711,23 @@ public class RouterActivity extends AppCompatActivity {
running++; running++;
} else { } else {
running--; running--;
if (running <= 0 && getActivityContext() != null) { if (running <= 0) {
getActivityContext().getSupportFragmentManager() getActivityContext().ifPresent(context -> context.getSupportFragmentManager()
.beginTransaction().remove(this).commit(); .beginTransaction().remove(this).commit());
} }
} }
} }
public interface ResultRunnable {
void run(AppCompatActivity context);
}
@Override @Override
public void onAttach(@NonNull final Context activityContext) { public void onAttach(@NonNull final Context activityContext) {
super.onAttach(activityContext); super.onAttach(activityContext);
context = new WeakReference<>((AppCompatActivity) activityContext); weakContext = new WeakReference<>((AppCompatActivity) activityContext);
}
@Override
public void onDetach() {
super.onDetach();
weakContext = null;
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -741,12 +743,13 @@ public class RouterActivity extends AppCompatActivity {
disposables.clear(); disposables.clear();
} }
private AppCompatActivity getActivityContext() { /**
return context == null ? null : context.get(); * @return the activity context, if there is one and the activity is not finishing
} */
private Optional<AppCompatActivity> getActivityContext() {
private boolean activityGone() { return Optional.ofNullable(weakContext)
return getActivityContext() == null || getActivityContext().isFinishing(); .flatMap(context -> Optional.ofNullable(context.get()))
.filter(context -> !context.isFinishing());
} }
// guard against IllegalStateException in calling DialogFragment.show() whilst in background // guard against IllegalStateException in calling DialogFragment.show() whilst in background
@ -754,60 +757,56 @@ public class RouterActivity extends AppCompatActivity {
// the network request to return) when it internally calls FragmentTransaction.commit() // the network request to return) when it internally calls FragmentTransaction.commit()
// after the FragmentManager has saved its states (isStateSaved() == true) // after the FragmentManager has saved its states (isStateSaved() == true)
// (ref: https://stackoverflow.com/a/39813506) // (ref: https://stackoverflow.com/a/39813506)
private void runOnVisible(final ResultRunnable runnable) { private void runOnVisible(final Consumer<AppCompatActivity> runnable) {
if (activityGone()) { getActivityContext().ifPresentOrElse(context -> {
inFlight(false); if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
return; context.runOnUiThread(() -> {
} runnable.accept(context);
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { inFlight(false);
getActivityContext().runOnUiThread(() -> { });
runnable.run(getActivityContext()); } else {
inFlight(false); getLifecycle().addObserver(new DefaultLifecycleObserver() {
}); @Override
} else { public void onResume(@NonNull final LifecycleOwner owner) {
getLifecycle().addObserver(new DefaultLifecycleObserver() { getLifecycle().removeObserver(this);
@Override getActivityContext().ifPresentOrElse(context ->
public void onResume(@NonNull final LifecycleOwner owner) { context.runOnUiThread(() -> {
getLifecycle().removeObserver(this); runnable.accept(context);
if (activityGone()) { inFlight(false);
inFlight(false); }),
return; () -> inFlight(false)
);
} }
getActivityContext().runOnUiThread(() -> { });
runnable.run(getActivityContext()); // this trick doesn't seem to work on Android 10+ (API 29)
inFlight(false); // which places restrictions on starting activities from the background
}); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
&& !context.isChangingConfigurations()) {
// try to bring the activity back to front if minimised
final Intent i = new Intent(context, RouterActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);
} }
});
// this trick doesn't seem to work on Android 10+ (API 29)
// which places restrictions on starting activities from the background
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
&& !getActivityContext().isChangingConfigurations()) {
// try to bring the activity back to front if minimised
final Intent i = new Intent(getActivityContext(), RouterActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);
} }
}
}, () -> {
// this branch is executed if there is no activity context
inFlight(false);
});
} }
<T> SingleTransformer<T, T> pleaseWait() { <T> Single<T> pleaseWait(final Single<T> single) {
return single -> single // 'abuse' ambWith() here to cancel the toast for us when the wait is over
// 'abuse' ambWith() here to cancel the toast for us when the wait is over return single.ambWith(Single.create(emitter -> getActivityContext().ifPresent(context ->
.ambWith(Single.create(emitter -> { context.runOnUiThread(() -> {
if (!activityGone()) { // Getting the stream info usually takes a moment
getActivityContext().runOnUiThread(() -> { // Notifying the user here to ensure that no confusion arises
// Getting the stream info usually takes a moment final Toast toast = Toast.makeText(context,
// Notifying the user here to ensure that no confusion arises getString(R.string.processing_may_take_a_moment),
final Toast t = Toast.makeText( Toast.LENGTH_LONG);
getActivityContext().getApplicationContext(), toast.show();
getString(R.string.processing_may_take_a_moment), emitter.setCancellable(toast::cancel);
Toast.LENGTH_LONG); }))));
t.show();
emitter.setCancellable(t::cancel);
});
}
}));
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
@ -816,7 +815,7 @@ public class RouterActivity extends AppCompatActivity {
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true) disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.compose(pleaseWait()) .compose(this::pleaseWait)
.subscribe(result -> .subscribe(result ->
runOnVisible(ctx -> { runOnVisible(ctx -> {
final FragmentManager fm = ctx.getSupportFragmentManager(); final FragmentManager fm = ctx.getSupportFragmentManager();
@ -833,23 +832,18 @@ public class RouterActivity extends AppCompatActivity {
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false) disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.compose(pleaseWait()) .compose(this::pleaseWait)
.subscribe( .subscribe(
info -> { info -> getActivityContext().ifPresent(context ->
if (!activityGone()) { PlaylistDialog.createCorrespondingDialog(context,
PlaylistDialog.createCorrespondingDialog( List.of(new StreamEntity(info)),
getActivityContext(), playlistDialog -> runOnVisible(ctx -> {
List.of(new StreamEntity(info)), // dismiss listener to be handled by FragmentManager
playlistDialog -> final FragmentManager fm =
runOnVisible(ctx -> { ctx.getSupportFragmentManager();
// dismiss listener to be handled by FragmentManager playlistDialog.show(fm, "addToPlaylistDialog");
final FragmentManager fm = })
ctx.getSupportFragmentManager(); )),
playlistDialog.show(fm, "addToPlaylistDialog");
})
);
}
},
throwable -> runOnVisible(ctx -> handleError(ctx, new ErrorInfo( throwable -> runOnVisible(ctx -> handleError(ctx, new ErrorInfo(
throwable, throwable,
UserAction.REQUESTED_STREAM, UserAction.REQUESTED_STREAM,