Skip to content

Commit 40442f3

Browse files
devlearnerStypox
authored andcommitted
Utilize Lifecycle observer
I thought it would have required an extra dependency; apparently that doesn't seem to be the case...
1 parent 61da167 commit 40442f3

1 file changed

Lines changed: 46 additions & 57 deletions

File tree

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

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
import androidx.fragment.app.DialogFragment;
3737
import androidx.fragment.app.Fragment;
3838
import androidx.fragment.app.FragmentManager;
39+
import androidx.lifecycle.DefaultLifecycleObserver;
40+
import androidx.lifecycle.Lifecycle;
41+
import androidx.lifecycle.LifecycleOwner;
3942
import androidx.preference.PreferenceManager;
4043

4144
import org.schabi.newpipe.database.stream.model.StreamEntity;
@@ -88,7 +91,6 @@
8891
import java.util.ArrayList;
8992
import java.util.Arrays;
9093
import java.util.List;
91-
import java.util.Vector;
9294

9395
import icepick.Icepick;
9496
import icepick.State;
@@ -213,6 +215,7 @@ protected void onDestroy() {
213215
if (dismissListener != null) {
214216
getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(dismissListener);
215217
}
218+
216219
disposables.clear();
217220
}
218221

@@ -699,9 +702,20 @@ private boolean canHandleChoiceLikeShowInfo(final String selectedChoiceKey) {
699702

700703
public static class PersistentFragment extends Fragment {
701704
private WeakReference<AppCompatActivity> context;
702-
private boolean isPaused = true;
703-
private final Vector<ResultRunnable> buffer = new Vector<>();
704705
private final CompositeDisposable disposables = new CompositeDisposable();
706+
private int running = 0;
707+
708+
private synchronized void inFlight(final boolean started) {
709+
if (started) {
710+
running++;
711+
} else {
712+
running--;
713+
if (running <= 0 && getActivityContext() != null) {
714+
getActivityContext().getSupportFragmentManager()
715+
.beginTransaction().remove(this).commit();
716+
}
717+
}
718+
}
705719

706720
public interface ResultRunnable {
707721
void run(AppCompatActivity context);
@@ -726,59 +740,44 @@ public void onDestroy() {
726740
disposables.clear();
727741
}
728742

729-
@Override
730-
public void onPause() {
731-
isPaused = true;
732-
super.onPause();
733-
}
734-
735-
@Override
736-
public void onResume() {
737-
isPaused = false;
738-
playback();
739-
super.onResume();
740-
}
741-
742743
private AppCompatActivity getActivityContext() {
743744
return context == null ? null : context.get();
744745
}
745746

747+
private boolean activityGone() {
748+
return getActivityContext() == null || getActivityContext().isFinishing();
749+
}
750+
746751
// guard against IllegalStateException in calling DialogFragment.show() whilst in background
747752
// (which could happen, say, when the user pressed the home button while waiting for
748753
// the network request to return) when it internally calls FragmentTransaction.commit()
749754
// after the FragmentManager has saved its states (isStateSaved() == true)
750755
// (ref: https://stackoverflow.com/a/39813506)
751-
private void playback() {
752-
if (activityGone()) {
753-
done();
754-
return;
755-
}
756-
if (buffer.size() == 0 || isPaused) {
757-
return;
758-
}
759-
while (buffer.size() > 0) {
760-
final ResultRunnable runnable = buffer.elementAt(0);
761-
buffer.removeElementAt(0);
762-
getActivityContext().runOnUiThread(() ->
763-
// execute queued task with new context, in case activity has been recreated
764-
runnable.run(getActivityContext())
765-
);
766-
}
767-
done();
768-
}
769-
private boolean activityGone() {
770-
return getActivityContext() == null || getActivityContext().isFinishing();
771-
}
772-
773-
// a DefaultLifecycleObserver is probably a good candidate here, but for now
774-
// let's stick with a vanilla approach to avoid pulling in an extra artifact just for this
775756
private void runOnVisible(final ResultRunnable runnable) {
776757
if (activityGone()) {
777-
done();
758+
inFlight(false);
778759
return;
779760
}
780-
if (isPaused) {
781-
buffer.add(runnable);
761+
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
762+
getActivityContext().runOnUiThread(() -> {
763+
runnable.run(getActivityContext());
764+
inFlight(false);
765+
});
766+
} else {
767+
getLifecycle().addObserver(new DefaultLifecycleObserver() {
768+
@Override
769+
public void onResume(@NonNull final LifecycleOwner owner) {
770+
getLifecycle().removeObserver(this);
771+
if (activityGone()) {
772+
inFlight(false);
773+
return;
774+
}
775+
getActivityContext().runOnUiThread(() -> {
776+
runnable.run(getActivityContext());
777+
inFlight(false);
778+
});
779+
}
780+
});
782781
// this trick doesn't seem to work on Android 10+ (API 29)
783782
// which places restrictions on starting activities from the background
784783
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
@@ -788,23 +787,12 @@ private void runOnVisible(final ResultRunnable runnable) {
788787
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
789788
startActivity(i);
790789
}
791-
} else {
792-
getActivityContext().runOnUiThread(() -> {
793-
runnable.run(getActivityContext());
794-
done();
795-
});
796-
}
797-
}
798-
799-
private void done() {
800-
if (getActivityContext() != null) {
801-
getActivityContext().getSupportFragmentManager()
802-
.beginTransaction().remove(this).commit();
803790
}
804791
}
805792

806793
@SuppressLint("CheckResult")
807-
protected void openDownloadDialog(final int currentServiceId, final String currentUrl) {
794+
private void openDownloadDialog(final int currentServiceId, final String currentUrl) {
795+
inFlight(true);
808796
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
809797
.subscribeOn(Schedulers.io())
810798
.observeOn(AndroidSchedulers.mainThread())
@@ -820,6 +808,7 @@ protected void openDownloadDialog(final int currentServiceId, final String curre
820808
}
821809

822810
private void openAddToPlaylistDialog(final int currentServiceId, final String currentUrl) {
811+
inFlight(true);
823812
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false)
824813
.subscribeOn(Schedulers.io())
825814
.observeOn(AndroidSchedulers.mainThread())
@@ -870,7 +859,7 @@ private PersistentFragment getPersistFragment() {
870859
return persistFragment;
871860
}
872861

873-
protected void pleaseWait() {
862+
private void pleaseWait() {
874863
// Getting the stream info usually takes a moment
875864
// Notifying the user here to ensure that no confusion arises
876865
Toast.makeText(

0 commit comments

Comments
 (0)